From 4d82e2b0a525346a1094c9ec44cf4728cef4f155 Mon Sep 17 00:00:00 2001 From: jie Date: Thu, 22 Feb 2024 20:36:02 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=9F=B3=E9=A2=91=E7=BB=93?= =?UTF-8?q?=E6=9E=84=EF=BC=8C=20=E6=B7=BB=E5=8A=A0MediaParam=EF=BC=8C=20?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0bugList?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/audioDecoder.h | 0 include/{videoDecoder.h => decodeParam.h} | 35 +++++++++++++--------- include/mediaDecoder.h | 17 +++++++++++ main.cc | 32 ++++++++++---------- src/audioDecoder.cc | 2 ++ src/{videoDecoder.cc => mediaDecoder.cc} | 36 +++++++++++------------ todo.txt | 1 + 7 files changed, 74 insertions(+), 49 deletions(-) create mode 100644 include/audioDecoder.h rename include/{videoDecoder.h => decodeParam.h} (84%) create mode 100644 include/mediaDecoder.h create mode 100644 src/audioDecoder.cc rename src/{videoDecoder.cc => mediaDecoder.cc} (76%) diff --git a/include/audioDecoder.h b/include/audioDecoder.h new file mode 100644 index 0000000..e69de29 diff --git a/include/videoDecoder.h b/include/decodeParam.h similarity index 84% rename from include/videoDecoder.h rename to include/decodeParam.h index ff2ac4b..6904682 100644 --- a/include/videoDecoder.h +++ b/include/decodeParam.h @@ -1,14 +1,5 @@ -#ifndef DECODER_H -#define DECODER_H -extern "C" { -#include "libavcodec/avcodec.h" -#include "libavformat/avformat.h" -#include "libavutil/imgutils.h" -} -#include -#include -#include - +#ifndef DECODEPARAM_H +#define DECODEPARAM_H template requires std::is_same_v || std::is_same_v struct MediaQueue @@ -103,7 +94,23 @@ struct VideoParam bool quit = false; }; -void InitDecoder(const char* filepath, VideoParam& param); -void RequestPacket(VideoParam& param); -void RequestFrame(VideoParam& param); +struct AudioParam +{ + MediaQueue packetQueue; + MediaQueue frameQueue; + AVFormatContext* fmtCtx; + AVCodecContext* codecCtx; + int audioStreamIndex; + + bool eof = false; + + bool pause = false; + bool quit = false; +}; + +struct MediaParam +{ + VideoParam videoParam; + AudioParam audioParam; +}; #endif \ No newline at end of file diff --git a/include/mediaDecoder.h b/include/mediaDecoder.h new file mode 100644 index 0000000..f00f4c6 --- /dev/null +++ b/include/mediaDecoder.h @@ -0,0 +1,17 @@ +#ifndef DECODER_H +#define DECODER_H +extern "C" { +#include "libavcodec/avcodec.h" +#include "libavformat/avformat.h" +#include "libavutil/imgutils.h" +} +#include +#include +#include + +#include "decodeParam.h" + +void InitDecoder(const char* filepath, VideoParam& param); +void RequestPacket(MediaParam& param); +void RequestVideoFrame(MediaParam& param); +#endif \ No newline at end of file diff --git a/main.cc b/main.cc index d7a378a..29678ec 100644 --- a/main.cc +++ b/main.cc @@ -6,7 +6,7 @@ #include #include "util.h" -#include "videoDecoder.h" +#include "mediaDecoder.h" #include "shaderService.h" #include "shader.h" using std::cout; @@ -18,14 +18,14 @@ struct OpenglVideoParam unsigned int texs[3]; }; -int InitVideo(SDL_Window*& window, const char* targetFilepath, VideoParam& videoParam, OpenglVideoParam& openglVideoParam, ShaderService*& shaderService) +int InitVideo(SDL_Window*& window, const char* targetFilepath, MediaParam& param, OpenglVideoParam& openglVideoParam, ShaderService*& shaderService) { - InitDecoder(targetFilepath, videoParam); + InitDecoder(targetFilepath, param.videoParam); //FIX: when app exited, the fmtCtx was freed, so need notify decode thread to stop decode and exit. - std::jthread(RequestPacket, std::ref(videoParam)).detach(); - std::jthread(RequestFrame, std::ref(videoParam)).detach(); - const int client_width = videoParam.width / 2; - const int client_height = videoParam.height / 2; + std::jthread(RequestPacket, std::ref(param)).detach(); + std::jthread(RequestVideoFrame, std::ref(param)).detach(); + const int client_width = param.videoParam.width / 2; + const int client_height = param.videoParam.height / 2; window = SDL_CreateWindow( "MP", SDL_WINDOWPOS_UNDEFINED, @@ -125,10 +125,10 @@ void InitImg(SDL_Window*& window, const char* filepath, SDL_Renderer*& renderer, texture = SDL_CreateTextureFromSurface(renderer, surface); } -void OpenglRenderVideo(VideoParam& videoParam, const OpenglVideoParam& openglVideoParam, ShaderService* shaderService) +void OpenglRenderVideo(MediaParam& param, const OpenglVideoParam& openglVideoParam, ShaderService* shaderService) { AVFrame* frame = av_frame_alloc(); - videoParam.frameQueue.pop(frame, true, videoParam.quit); + param.videoParam.frameQueue.pop(frame, true, param.videoParam.quit); // TODO: TIMER glBindTexture(GL_TEXTURE_2D, openglVideoParam.texs[0]); glPixelStoref(GL_UNPACK_ROW_LENGTH, static_cast(frame->linesize[0])); @@ -171,9 +171,8 @@ int main(int argc, char** argv) // INIT - int client_width, client_height; SDL_Window* window = nullptr; - VideoParam videoParam{}; + MediaParam mediaParam{}; OpenglVideoParam openglVideoParam{}; ShaderService* shaderService = nullptr; SDL_Surface* surface = nullptr; @@ -189,8 +188,8 @@ int main(int argc, char** argv) { case FileType::VIDEO: { - InitVideo(window, targetFilepath, videoParam, openglVideoParam, shaderService); - const auto stream_frame_rate = videoParam.fmtCtx->streams[videoParam.videoStreamIndex]->avg_frame_rate; + InitVideo(window, targetFilepath, mediaParam, openglVideoParam, shaderService); + const auto stream_frame_rate = mediaParam.videoParam.fmtCtx->streams[mediaParam.videoParam.videoStreamIndex]->avg_frame_rate; framerate = static_cast(stream_frame_rate.den) / stream_frame_rate.num; break; } @@ -238,11 +237,10 @@ int main(int argc, char** argv) switch (fileType) { case FileType::VIDEO: - OpenglRenderVideo(videoParam, openglVideoParam, shaderService); + OpenglRenderVideo(mediaParam, openglVideoParam, shaderService); SDL_GL_SwapWindow(window); std::this_thread::sleep_until(current_time + std::chrono::milliseconds(30)); current_time = std::chrono::system_clock::now(); - cout << SDL_GetTicks() << '\n'; break; case FileType::IMG: RenderPicture(window, renderer, texture); @@ -252,8 +250,8 @@ int main(int argc, char** argv) } } - avcodec_close(videoParam.codecCtx); - avformat_close_input(&(videoParam.fmtCtx)); + avcodec_close(mediaParam.videoParam.codecCtx); + avformat_close_input(&(mediaParam.videoParam.fmtCtx)); SDL_GL_DeleteContext(openglVideoParam.glContext); SDL_DestroyWindow(window); SDL_Quit(); diff --git a/src/audioDecoder.cc b/src/audioDecoder.cc new file mode 100644 index 0000000..459fbcc --- /dev/null +++ b/src/audioDecoder.cc @@ -0,0 +1,2 @@ +#include"audioDecoder.h" + diff --git a/src/videoDecoder.cc b/src/mediaDecoder.cc similarity index 76% rename from src/videoDecoder.cc rename to src/mediaDecoder.cc index 7e6c326..1670ab2 100644 --- a/src/videoDecoder.cc +++ b/src/mediaDecoder.cc @@ -1,4 +1,4 @@ -#include "videoDecoder.h" +#include "mediaDecoder.h" #include #include using namespace std::literals::chrono_literals; @@ -26,31 +26,32 @@ void InitDecoder(const char* filepath, VideoParam& param) { param.height = codecFmt->height; } -void RequestPacket(VideoParam& param) { - const auto& fmtCtx = param.fmtCtx; - const auto& videoStreamIndex = param.videoStreamIndex; +void RequestPacket(MediaParam& param) { + const auto& fmtCtx = param.videoParam.fmtCtx; + const auto& videoStreamIndex = param.videoParam.videoStreamIndex; AVPacket* packet = av_packet_alloc(); while (true) { - if (param.packetQueue.isFill()) { + if (param.videoParam.packetQueue.isFill()) { std::this_thread::sleep_for(100ms); continue; } //FIX: const int ret = av_read_frame(fmtCtx, packet); - if (param.eof) { + if (param.videoParam.eof) { std::this_thread::sleep_for(100ms); + av_packet_unref(packet); return; } if (ret == 0) { if (packet->stream_index == videoStreamIndex) { - param.packetQueue.push(packet); + param.videoParam.packetQueue.push(packet); av_packet_unref(packet); } else if (ret == AVERROR_EOF) { - param.eof = true; + param.videoParam.eof = true; av_packet_unref(packet); break; } @@ -58,28 +59,27 @@ void RequestPacket(VideoParam& param) { av_packet_unref(packet); } } - else if (param.fmtCtx->pb->error == 0) { + else if (param.videoParam.fmtCtx->pb->error == 0) { std::this_thread::sleep_for(100ms); } } av_packet_unref(packet); } -void RequestFrame(VideoParam& param) { - const auto& fmtCtx = param.fmtCtx; - const auto& codecCtx = param.codecCtx; - const auto& videoStreamIndex = param.videoStreamIndex; +void RequestVideoFrame(MediaParam& param) { + const auto& fmtCtx = param.videoParam.fmtCtx; + const auto& codecCtx = param.videoParam.codecCtx; + const auto& videoStreamIndex = param.videoParam.videoStreamIndex; AVPacket* packet = av_packet_alloc(); AVFrame* frame = av_frame_alloc(); - //frame->format = AV_PIX_FMT_YUV420P; while (true) { - if (param.frameQueue.isFill()) { + if (param.videoParam.frameQueue.isFill()) { std::this_thread::sleep_for(30ms); continue; } - if (!param.packetQueue.pop(packet, true, param.quit)) { - if (param.quit) + if (!param.videoParam.packetQueue.pop(packet, true, param.videoParam.quit)) { + if (param.videoParam.quit) { av_packet_unref(packet); av_frame_unref(frame); @@ -97,7 +97,7 @@ void RequestFrame(VideoParam& param) { { continue; } - param.frameQueue.push(frame); + param.videoParam.frameQueue.push(frame); av_frame_unref(frame); } } diff --git a/todo.txt b/todo.txt index 0c859dd..0697416 100644 --- a/todo.txt +++ b/todo.txt @@ -1,5 +1,6 @@ bug: 1. 退出时异常 + 2. 内存泄露 todo: 1. 添加音频播放