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; }
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; }
/** * @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; }