//文件处理函数,主要负责将视频文件解析成视频数据包和音频数据包 //并分别插入这两个队列。 void* demux(void* filename) { AVPacket *pPacket = NULL; while (true) { pPacket = (AVPacket *)av_malloc(sizeof(AVPacket)); av_init_packet(pPacket); //fflush(stdout); if (av_read_frame(g_player_ctx->fmt_ctx, pPacket) < 0) { av_free(pPacket); //printf("wrong packet\n"); continue; } //av_dup_packet(pPacket); if (g_player_ctx->video_id == pPacket->stream_index) { push_to_queue(&video_pkt_queue, pPacket); } else if (g_player_ctx->audio_id == pPacket->stream_index) { push_to_queue(&audio_pkt_queue, pPacket); } else { av_free_packet(pPacket); //av_free(pPacket); continue; } } printf("file handler thread exit!\n"); av_free_packet(pPacket); return NULL; }
void* audio_decoder(void* param) { int got_frame = 0; int data_len = 0; AVPacket *packet = NULL; AVFrame *audio_frame = NULL; //av_rescale_q while (true) { Sleep(20); packet = (AVPacket*)pop_from_queue(&audio_pkt_queue); if (packet == NULL) continue; while (true) { audio_frame = avcodec_alloc_frame(); if (!audio_frame) return (void*)AVERROR(ENOMEM); //一个packet可能有多个音频的frame, 所以有了这个循环,用到了这个data_len data_len = avcodec_decode_audio4(g_player_ctx->audio_codec_ctx, audio_frame, &got_frame, packet); //printf("the frame len is %d\n", data_len); if (data_len < 0) { printf("decode packet failed\n"); av_free(audio_frame); break;//解包出现问题,跳过此包 } packet->data += data_len; packet->size -= data_len; if (!got_frame) { if ((audio_frame->data[0]) != NULL) printf("no empty\n"); av_free(audio_frame); break;//完成整个packet的解包,跳出当前循环 } push_to_queue(&audio_sam_queue, audio_frame); } //packet处理完成,释放内存 av_free(packet); } return NULL; }
int main() { int N=100, i; int *data; struct work_queue* wq = alloc_queue(1000, "Num queue"); for(i=0;i<N;i++) { push_to_queue(wq,i); } printf("Done pushing %d elements\n", N); printf("Size of queue is %d elements\n", get_queue_size(wq)); i=0; while(data = pop(wq)) { printf("%d\n",*data); i++; } printf("Popped out %d elements\n", i); printf("Size of queue is %d elements\n", get_queue_size(wq)); return 0; }
void perf_test(const size_t num_producers, const size_t num_elements_to_produce, const size_t num_consumers) { std::cout << "start perf test..." << std::endl; ts_queue_t q; barrier start_barrier(num_producers + num_consumers); std::atomic_size_t producers_done_cnt(0); steady_timer timer; std::vector<std::future<int_t>> producers; for (size_t i = 0; i < num_producers; ++i) { auto producer = [&]() { start_barrier.enter(); std::random_device random_dev; std::mt19937 mt_random_engine(random_dev()); std::uniform_int_distribution<int_t> gen_random_int(1, 1000000); int_t produced_sum = 0; for (size_t k = 0; k < num_elements_to_produce; ++k) { auto e = gen_random_int(mt_random_engine); push_to_queue(q, e); produced_sum += e; pause(e); } producers_done_cnt.fetch_add(1); return produced_sum; }; producers.push_back(std::async(producer)); } std::vector<std::future<int_t>> consumers; for (size_t i = 0; i < num_consumers; ++i) { auto consumer = [&]() { start_barrier.enter(); int_t consumed_sum = 0; do { consumed_sum += pop_from_queue_while_not_empty(q); std::this_thread::yield(); } while (producers_done_cnt != num_producers); consumed_sum += pop_from_queue_while_not_empty(q); return consumed_sum; }; consumers.push_back(std::async(consumer)); } int_t produced_sum = 0; for (auto& f : producers) { produced_sum += f.get(); } int_t consumed_sum = 0; for (auto& f : consumers) { consumed_sum += f.get(); } double elapsed = timer.seconds_elapsed(); std::cout << "perf test: num producers = " << num_producers << ", num_consumers = " << num_consumers << std::endl; std::cout << "produced sum = " << produced_sum << std::endl; std::cout << "consumed sum = " << consumed_sum << std::endl; std::cout << "result: " << ((produced_sum == consumed_sum) ? "SUCCEEDED" : "FAILED") << std::endl; std::cout << "test takes " << elapsed << " seconds" << std::endl; }