Beispiel #1
0
int vp8_create_decoder_instances(struct frame_buffers *fb, VP8D_CONFIG *oxcf) {
  /* decoder instance for single thread mode */
  fb->pbi[0] = create_decompressor(oxcf);
  if (!fb->pbi[0]) return VPX_CODEC_ERROR;

#if CONFIG_MULTITHREAD
  if (setjmp(fb->pbi[0]->common.error.jmp)) {
    vp8_remove_decoder_instances(fb);
    memset(fb->pbi, 0, sizeof(fb->pbi));
    vpx_clear_system_state();
    return VPX_CODEC_ERROR;
  }

  fb->pbi[0]->common.error.setjmp = 1;
  fb->pbi[0]->max_threads = oxcf->max_threads;
  vp8_decoder_create_threads(fb->pbi[0]);
  fb->pbi[0]->common.error.setjmp = 0;
#endif
  return VPX_CODEC_OK;
}
Beispiel #2
0
int vp8_create_decoder_instances(struct frame_buffers *fb, VP8D_CONFIG *oxcf)
{
    if(!fb->use_frame_threads)
    {
        /* decoder instance for single thread mode */
        fb->pbi[0] = create_decompressor(oxcf);
        if(!fb->pbi[0])
            return VPX_CODEC_ERROR;

#if CONFIG_MULTITHREAD
        /* enable row-based threading only when use_frame_threads
         * is disabled */
        fb->pbi[0]->max_threads = oxcf->max_threads;
        vp8_decoder_create_threads(fb->pbi[0]);
#endif
    }
    else
    {
        /* TODO : create frame threads and decoder instances for each
         * thread here */
    }

    return VPX_CODEC_OK;
}
Beispiel #3
0
/**
 * @brief Decompress one ROHC packet and compare the result with a reference
 *
 * @param decomp           The decompressor to use to decompress the ROHC packet
 * @param num_packet       A number affected to the IP packet to compress/decompress
 * @param header           The PCAP header for the packet
 * @param packet           The packet to compress/decompress (link layer included)
 * @param link_len_src     The length of the link layer header before IP data
 * @param cmp_packet       The ROHC packet for comparison purpose
 * @param cmp_size         The size of the ROHC packet used for comparison
 *                         purpose
 * @param link_len_cmp     The length of the link layer header before ROHC data
 * @return                 0 if the process is successful
 *                         -1 if ROHC packet is malformed
 *                         -2 if decompression fails
 *                         -3 if the decompressed packet doesn't match the
 *                            reference
 */
static int test_decomp_one(struct rohc_decomp *const decomp,
                           const size_t num_packet,
                           const struct pcap_pkthdr header,
                           const unsigned char *const packet,
                           const size_t link_len_src,
                           const unsigned char *const cmp_packet,
                           const size_t cmp_size,
                           const size_t link_len_cmp)
{
	const struct rohc_ts arrival_time = { .sec = 0, .nsec = 0 };
	struct rohc_buf rohc_packet =
		rohc_buf_init_full((uint8_t *) packet, header.caplen, arrival_time);
	uint8_t uncomp_buffer[MAX_ROHC_SIZE];
	struct rohc_buf uncomp_packet =
		rohc_buf_init_empty(uncomp_buffer, MAX_ROHC_SIZE);
	rohc_status_t status;

	printf("=== decompressor packet #%zu:\n", num_packet);

	/* check Ethernet frame length */
	if(header.len <= link_len_src || header.len != header.caplen)
	{
		fprintf(stderr, "bad PCAP packet (len = %u, caplen = %u)\n",
		        header.len, header.caplen);
		goto error_fmt;
	}
	if(cmp_packet != NULL && cmp_size <= link_len_cmp)
	{
		fprintf(stderr, "bad comparison packet: too small for link header\n");
		goto error_fmt;
	}

	/* skip the link layer header */
	rohc_buf_pull(&rohc_packet, link_len_src);

	/* decompress the ROHC packet */
	printf("=== ROHC decompression: start\n");
	status = rohc_decompress3(decomp, rohc_packet, &uncomp_packet, NULL, NULL);
	if(status != ROHC_STATUS_OK)
	{
		size_t i;

		printf("=== ROHC decompression: failure\n");
		printf("=== original %zu-byte compressed packet:\n", rohc_packet.len);
		for(i = 0; i < rohc_packet.len; i++)
		{
			if(i > 0 && (i % 16) == 0)
			{
				printf("\n");
			}
			else if(i > 0 && (i % 8) == 0)
			{
				printf("  ");
			}
			printf("%02x ", rohc_buf_byte_at(rohc_packet, i));
		}
		printf("\n\n");
		goto error_decomp;
	}
	printf("=== ROHC decompression: success\n");

	/* compare the decompressed packet with the original one */
	printf("=== uncompressed packet comparison: start\n");
	if(cmp_packet && !compare_packets(rohc_buf_data(uncomp_packet),
	                                  uncomp_packet.len,
	                                  cmp_packet + link_len_cmp,
	                                  cmp_size - link_len_cmp))
	{
		printf("=== uncompressed packet comparison: failure\n");
		printf("\n");
		goto error_cmp;
	}
	printf("=== uncompressed packet comparison: success\n");

	printf("\n");
	return 0;

error_fmt:
	return -1;
error_decomp:
	return -2;
error_cmp:
	return -3;
}


/**
 * @brief Test the ROHC library decompression with a flow of ROHC packets
 *        generated by another ROHC implementation
 *
 * @param cid_type             The type of CIDs the compressor shall use
 * @param wlsb_width           The width of the WLSB window to use
 * @param max_contexts         The maximum number of ROHC contexts to use
 * @param src_filename         The name of the PCAP file that contains the
 *                             ROHC packets to decompress
 * @param cmp_filename         The name of the PCAP file that contains the
 *                             uncompressed packets used for comparison
 * @return                     0 in case of success,
 *                             1 in case of failure,
 *                             77 if test is skipped
 */
static int test_decomp_all(const rohc_cid_type_t cid_type,
                           const size_t wlsb_width,
                           const size_t max_contexts,
                           const char *const src_filename,
                           const char *const cmp_filename)
{
	char errbuf[PCAP_ERRBUF_SIZE];

	pcap_t *handle;
	struct pcap_pkthdr header;
	int link_layer_type_src;
	size_t link_len_src;
	unsigned char *packet;

	pcap_t *cmp_handle;
	struct pcap_pkthdr cmp_header;
	int link_layer_type_cmp;
	size_t link_len_cmp = 0;
	unsigned char *cmp_packet;

	size_t counter;

	struct rohc_decomp *decomp;

	size_t nb_bad = 0;
	size_t nb_ok = 0;
	size_t err_decomp = 0;
	size_t nb_ref = 0;

	int status = 1;
	int ret;

	printf("=== initialization:\n");

	/* open the source dump file */
	handle = pcap_open_offline(src_filename, errbuf);
	if(handle == NULL)
	{
		printf("failed to open the source pcap file: %s\n", errbuf);
		goto error;
	}

	/* link layer in the source dump must be Ethernet */
	link_layer_type_src = pcap_datalink(handle);
	if(link_layer_type_src != DLT_EN10MB &&
	   link_layer_type_src != DLT_LINUX_SLL &&
	   link_layer_type_src != DLT_RAW &&
	   link_layer_type_src != DLT_NULL)
	{
		printf("link layer type %d not supported in source dump (supported = "
		       "%d, %d, %d, %d)\n", link_layer_type_src, DLT_EN10MB,
		       DLT_LINUX_SLL, DLT_RAW, DLT_NULL);
		status = 77; /* skip test */
		goto close_input;
	}

	if(link_layer_type_src == DLT_EN10MB)
	{
		link_len_src = ETHER_HDR_LEN;
	}
	else if(link_layer_type_src == DLT_LINUX_SLL)
	{
		link_len_src = LINUX_COOKED_HDR_LEN;
	}
	else if(link_layer_type_src == DLT_NULL)
	{
		link_len_src = BSD_LOOPBACK_HDR_LEN;
	}
	else /* DLT_RAW */
	{
		link_len_src = 0;
	}

	/* open the uncompressed comparison dump file if asked */
	if(cmp_filename != NULL)
	{
		cmp_handle = pcap_open_offline(cmp_filename, errbuf);
		if(cmp_handle == NULL)
		{
			printf("failed to open the comparison pcap file: %s\n", errbuf);
			goto close_input;
		}

		/* link layer in the rohc_comparison dump must be Ethernet */
		link_layer_type_cmp = pcap_datalink(cmp_handle);
		if(link_layer_type_cmp != DLT_EN10MB &&
		   link_layer_type_cmp != DLT_LINUX_SLL &&
		   link_layer_type_cmp != DLT_RAW &&
		   link_layer_type_cmp != DLT_NULL)
		{
			printf("link layer type %d not supported in comparision dump "
			       "(supported = %d, %d, %d, %d)\n", link_layer_type_cmp,
			       DLT_EN10MB, DLT_LINUX_SLL, DLT_RAW, DLT_NULL);
			status = 77; /* skip test */
			goto close_comparison;
		}

		if(link_layer_type_cmp == DLT_EN10MB)
		{
			link_len_cmp = ETHER_HDR_LEN;
		}
		else if(link_layer_type_cmp == DLT_LINUX_SLL)
		{
			link_len_cmp = LINUX_COOKED_HDR_LEN;
		}
		else if(link_layer_type_cmp == DLT_NULL)
		{
			link_len_cmp = BSD_LOOPBACK_HDR_LEN;
		}
		else /* DLT_RAW */
		{
			link_len_cmp = 0;
		}
	}
	else
	{
		cmp_handle = NULL;
	}

	/* create the decompressor */
	decomp = create_decompressor(cid_type, max_contexts);
	if(decomp == NULL)
	{
		printf("failed to create the decompressor 1\n");
		goto close_comparison;
	}

	printf("\n");

	/* for each ROHC packet in the dump */
	counter = 0;
	while((packet = (unsigned char *) pcap_next(handle, &header)) != NULL)
	{
		counter++;

		/* get next uncompressed packet from the comparison dump file if asked */
		if(cmp_handle != NULL)
		{
			cmp_packet = (unsigned char *) pcap_next(cmp_handle, &cmp_header);
		}
		else
		{
			cmp_packet = NULL;
			cmp_header.caplen = 0;
		}

		/* decompress one packet of the flow and compare it with the given
		 * reference */
		ret = test_decomp_one(decomp, counter,
		                      header, packet, link_len_src,
		                      cmp_packet, cmp_header.caplen, link_len_cmp);
		if(ret == 0)
		{
			nb_ok++;
		}
		else if(ret == -2)
		{
			err_decomp++;
		}
		else if(ret != -3)
		{
			nb_ref++;
		}
		else
		{
			nb_bad++;
		}
	}

	/* show the compression/decompression results */
	printf("=== summary:\n");
	printf("===\tpackets_processed:    %zu\n", counter);
	printf("===\tmalformed:            %zu\n", nb_bad);
	printf("===\tdecompression_failed: %zu\n", err_decomp);
	printf("===\tmatches:              %zu\n", nb_ok);
	printf("\n");

	/* show some info/stats about the decompressor */
	if(!show_rohc_decomp_stats(decomp))
	{
		fprintf(stderr, "failed to dump ROHC decompressor stats\n");
		goto free_decomp;
	}
	printf("\n");

	/* destroy the compressors and decompressors */
	printf("=== shutdown:\n");
	if(err_decomp == 0 && nb_bad == 0 && nb_ref == 0 && nb_ok == counter)
	{
		/* test is successful */
		status = 0;
	}

free_decomp:
	rohc_decomp_free(decomp);
close_comparison:
	if(cmp_handle != NULL)
	{
		pcap_close(cmp_handle);
	}
close_input:
	pcap_close(handle);
error:
	return status;
}