From 2641cb0bb308325e140649ff766bb1bd690aadad Mon Sep 17 00:00:00 2001 From: JIe Jie Date: Thu, 22 Feb 2024 11:45:01 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=9A=E7=BA=BF=E7=A8=8B=E8=A7=A3=E7=A0=81?= =?UTF-8?q?=E8=A7=86=E9=A2=91=E5=B8=A7,=20=E6=B7=BB=E5=8A=A0todo.txt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/decoder.h | 36 +++++++++++++++-------------- src/decoder.cc | 59 ++++++++++++++++++++++------------------------- todo.txt | 10 ++++++++ 3 files changed, 56 insertions(+), 49 deletions(-) create mode 100644 todo.txt diff --git a/include/decoder.h b/include/decoder.h index acf4266..ff2ac4b 100644 --- a/include/decoder.h +++ b/include/decoder.h @@ -11,11 +11,11 @@ extern "C" { template requires std::is_same_v || std::is_same_v -struct MediaQueue +struct MediaQueue { - static constexpr int MAX_SIZE = 500; + static constexpr int MAX_SIZE = 30; bool full = false; - std::queue queue; + std::queue queue; std::condition_variable cv; std::mutex mut; @@ -38,14 +38,15 @@ bool MediaQueue::push(const T* item) { auto temp = av_packet_alloc(); av_packet_ref(temp, item); size += temp->size; - queue.push(*temp); - }else if(std::is_same_v) { + queue.push(temp); + } + else if (std::is_same_v) { auto temp = av_frame_alloc(); av_frame_ref(temp, item); - queue.push(*temp); + queue.push(temp); } count++; - if(count >= MAX_SIZE) { + if (count >= MAX_SIZE) { full = true; } cv.notify_all(); @@ -57,23 +58,24 @@ bool MediaQueue::pop(T* item, bool block, bool quit) { std::unique_lock lock(mut); while (!quit) { if (!queue.empty()) { - T temp = queue.front(); if constexpr (std::is_same_v) { - if (av_packet_ref(item, &temp) < 0) { + AVPacket* temp = queue.front(); + if (av_packet_ref(item, temp) < 0) { return false; } - av_packet_unref(&temp); + av_packet_unref(temp); } else if (std::is_same_v) { - if (av_frame_ref(item, &temp) < 0) { + AVFrame* temp = queue.front(); + if (av_frame_ref(item, temp) < 0) { return false; } - av_frame_unref(&temp); + av_frame_unref(temp); } queue.pop(); count--; full = false; - return true; + return true; } else if (block) { cv.wait(lock); @@ -85,11 +87,10 @@ bool MediaQueue::pop(T* item, bool block, bool quit) { return false; } - struct VideoParam { - - MediaQueue queue; + MediaQueue packetQueue; + MediaQueue frameQueue; AVFormatContext* fmtCtx; AVCodecContext* codecCtx; int width; @@ -97,11 +98,12 @@ struct VideoParam int videoStreamIndex; bool eof = false; + bool pause = false; bool quit = false; }; void InitDecoder(const char* filepath, VideoParam& param); void RequestPacket(VideoParam& param); -AVFrame* RequestFrame(VideoParam& param); +void RequestFrame(VideoParam& param); #endif \ No newline at end of file diff --git a/src/decoder.cc b/src/decoder.cc index f44213b..a5a901a 100644 --- a/src/decoder.cc +++ b/src/decoder.cc @@ -33,7 +33,7 @@ void RequestPacket(VideoParam& param) { AVPacket* packet = av_packet_alloc(); while (true) { - if(param.queue.isFill()) { + if (param.packetQueue.isFill()) { std::this_thread::sleep_for(100ms); continue; } @@ -44,7 +44,7 @@ void RequestPacket(VideoParam& param) { } if (ret == 0) { if (packet->stream_index == videoStreamIndex) { - param.queue.push(packet); + param.packetQueue.push(packet); av_packet_unref(packet); } else if (ret == AVERROR_EOF) @@ -52,57 +52,52 @@ void RequestPacket(VideoParam& param) { param.eof = true; av_packet_unref(packet); break; - }else { + } + else { av_packet_unref(packet); } - }else if(param.fmtCtx->pb->error == 0) { + } + else if (param.fmtCtx->pb->error == 0) { std::this_thread::sleep_for(100ms); } } av_packet_unref(packet); } - -AVFrame* RequestFrame(VideoParam& param) { +void RequestFrame(VideoParam& param) { const auto& fmtCtx = param.fmtCtx; const auto& codecCtx = param.codecCtx; const auto& videoStreamIndex = param.videoStreamIndex; AVPacket* packet = av_packet_alloc(); AVFrame* frame = av_frame_alloc(); - + //frame->format = AV_PIX_FMT_YUV420P; while (true) { - if (!param.queue.pop(packet, true, param.quit)) { - if(param.quit) - //NOTE:if no need do something, just return nullptr - return nullptr; + if (param.frameQueue.isFill()) { + std::this_thread::sleep_for(30ms); + continue; + } + if (!param.packetQueue.pop(packet, true, param.quit)) { + if (param.quit) + { + av_packet_unref(packet); + av_frame_unref(frame); + return; + } continue; } int ret = avcodec_send_packet(codecCtx, packet); - if(ret < 0) { - av_packet_unref(packet); - av_frame_free(&frame); - return nullptr; + if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) { + continue; } - if (ret == 0) { - ret = avcodec_receive_frame(codecCtx, frame); - if (ret == 0) { - av_packet_unref(packet); - return frame; - } - if (ret == AVERROR(EAGAIN)) { - continue; - } - av_frame_free(&frame); - av_packet_free(&packet); - return nullptr; - } - if (ret == AVERROR_EOF) + + ret = avcodec_receive_frame(codecCtx, frame); + if (ret < 0 && ret != AVERROR_EOF) { - av_packet_unref(packet); - return nullptr; + continue; } - av_packet_unref(packet); + param.frameQueue.push(frame); + av_frame_unref(frame); } } diff --git a/todo.txt b/todo.txt new file mode 100644 index 0000000..0c859dd --- /dev/null +++ b/todo.txt @@ -0,0 +1,10 @@ +bug: + 1. 退出时异常 + +todo: + 1. 添加音频播放 + 2. 优化视频帧率同步 + 3. 添加音频操作 + 4. 添加视频操作 + 5. 优化内存 + 6. 优化代码