From 3697de0b4a10b688c4fb1de62b1ea617f0775875 Mon Sep 17 00:00:00 2001 From: Jie Date: Tue, 20 Feb 2024 16:45:03 +0800 Subject: [PATCH] add timer for play video --- main.cc | 132 +++++++++++++++++++++++++++---------------------- src/decoder.cc | 2 + 2 files changed, 76 insertions(+), 58 deletions(-) diff --git a/main.cc b/main.cc index 29edd3f..025bef6 100644 --- a/main.cc +++ b/main.cc @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -9,23 +10,25 @@ #include "shader.h" using std::cout, std::endl; -struct OpenglVideoParam{ +struct OpenglVideoParam +{ SDL_GLContext glContext; unsigned int VAO, VBO, EBO; unsigned int texs[3]; }; -int InitVideo(SDL_Window*& window, const char* targetFilepath, DecoderParam& decoderParam, OpenglVideoParam& openglVideoParam, ShaderService*& shaderService){ +int InitVideo(SDL_Window *&window, const char *targetFilepath, DecoderParam &decoderParam, OpenglVideoParam &openglVideoParam, ShaderService *&shaderService) +{ InitDecoder(targetFilepath, decoderParam); int client_width = decoderParam.width / 2; int client_height = decoderParam.height / 2; window = SDL_CreateWindow( - "MP", - SDL_WINDOWPOS_UNDEFINED, - SDL_WINDOWPOS_UNDEFINED, - client_width, - client_height, - SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL); + "MP", + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + client_width, + client_height, + SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL); if (!window) { cout << SDL_GetError() << "\n"; @@ -49,10 +52,10 @@ int InitVideo(SDL_Window*& window, const char* targetFilepath, DecoderParam& dec } float vertices[] = { - 1.f, 1.f, 0.0, 1.0, 0.0, - 1.f, -1.f, 0.0, 1.0, 1.0, + 1.f, 1.f, 0.0, 1.0, 0.0, + 1.f, -1.f, 0.0, 1.0, 1.0, -1.f, -1.f, 0.0, 0.0, 1.0, - -1.f, 1.f, 0.0, 0.0, 0.0}; + -1.f, 1.f, 0.0, 0.0, 0.0}; unsigned int indices[]{ 0, 1, @@ -91,77 +94,88 @@ int InitVideo(SDL_Window*& window, const char* targetFilepath, DecoderParam& dec shaderService->SetUniform("textureV", 2); return 0; } -void OpenglRender(DecoderParam& decoderParam, OpenglVideoParam& openglVideoParam, ShaderService* shaderService){ -auto frame = RequestFrame(decoderParam); - int64_t pts = frame->pts; - static bool first_frame = true; - // TODO: TIMER - SDL_Delay(100); +void OpenglRender(DecoderParam &decoderParam, OpenglVideoParam &openglVideoParam, ShaderService *shaderService) +{ + auto frame = RequestFrame(decoderParam); + if(frame == nullptr) + return; + int64_t pts = frame->pts; + static bool first_frame = true; + // TODO: TIMER + glBindTexture(GL_TEXTURE_2D, openglVideoParam.texs[0]); + glPixelStoref(GL_UNPACK_ROW_LENGTH, frame->linesize[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, frame->width, frame->height, 0, GL_RED, GL_UNSIGNED_BYTE, frame->data[0]); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, openglVideoParam.texs[0]); - glPixelStoref(GL_UNPACK_ROW_LENGTH, frame->linesize[0]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, frame->width, frame->height, 0, GL_RED, GL_UNSIGNED_BYTE, frame->data[0]); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, openglVideoParam.texs[1]); + glPixelStoref(GL_UNPACK_ROW_LENGTH, frame->linesize[1]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, frame->width / 2, frame->height / 2, 0, GL_RED, GL_UNSIGNED_BYTE, frame->data[1]); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, openglVideoParam.texs[1]); - glPixelStoref(GL_UNPACK_ROW_LENGTH, frame->linesize[1]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, frame->width / 2, frame->height / 2, 0, GL_RED, GL_UNSIGNED_BYTE, frame->data[1]); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, openglVideoParam.texs[2]); + glPixelStoref(GL_UNPACK_ROW_LENGTH, frame->linesize[2]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, frame->width / 2, frame->height / 2, 0, GL_RED, GL_UNSIGNED_BYTE, frame->data[2]); - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, openglVideoParam.texs[2]); - glPixelStoref(GL_UNPACK_ROW_LENGTH, frame->linesize[2]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, frame->width / 2, frame->height / 2, 0, GL_RED, GL_UNSIGNED_BYTE, frame->data[2]); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - - shaderService->Use(); - glBindVertexArray(openglVideoParam.VAO); - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); + shaderService->Use(); + glBindVertexArray(openglVideoParam.VAO); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); + av_frame_free(&frame); } int main(int argc, char **const argv) { - //Check File - const char* targetFilepath = argv[1]; - if(targetFilepath == nullptr || !std::filesystem::exists(targetFilepath)){ - cout<<"File Not Exist\n"; + // Check File + const char *targetFilepath = argv[1]; + if (targetFilepath == nullptr || !std::filesystem::exists(targetFilepath)) + { + cout << "File Not Exist\n"; return 0; } const FileType fileType = Util::GetFileType(targetFilepath); - if(fileType == FileType::ERRORTYPE){ - cout<<"unsupport file type\n"; + if (fileType == FileType::ERRORTYPE) + { + cout << "unsupport file type\n"; return 0; } - - //INIT + + // INIT int client_width, client_height; - SDL_Window* window = nullptr; + SDL_Window *window = nullptr; DecoderParam decoderParam{}; OpenglVideoParam openglVideoParam{}; - ShaderService* shaderService = nullptr; + ShaderService *shaderService = nullptr; + double framerate = .0f; if (SDL_Init(SDL_INIT_EVERYTHING) < 0) { cout << SDL_GetError() << "\n"; return -1; } - switch(fileType){ - case FileType::VIDEO:{ - InitVideo(window, targetFilepath, decoderParam, openglVideoParam, shaderService); - break; - } - case FileType::IMG:{ - break; - } - case FileType::MUSIC:{ - break; - } - default: - return -1; + switch (fileType) + { + case FileType::VIDEO: + { + InitVideo(window, targetFilepath, decoderParam, openglVideoParam, shaderService); + auto& time_base = decoderParam.fmtCtx->streams[decoderParam.videoStreamIndex]->time_base; + framerate = (double)time_base.num / time_base.den; + break; + } + case FileType::IMG: + { + break; + } + case FileType::MUSIC: + { + break; + } + default: + return -1; } bool quit = false; + auto current_time = std::chrono::system_clock::now(); SDL_Event event; while (!quit) { @@ -191,8 +205,10 @@ int main(int argc, char **const argv) case FileType::VIDEO: OpenglRender(decoderParam, openglVideoParam, shaderService); SDL_GL_SwapWindow(window); + std::this_thread::sleep_until(current_time + std::chrono::milliseconds((int)(framerate * 1000))); + current_time = std::chrono::system_clock::now(); break; - + default: break; } diff --git a/src/decoder.cc b/src/decoder.cc index c306b94..2ba4dd2 100644 --- a/src/decoder.cc +++ b/src/decoder.cc @@ -41,6 +41,8 @@ AVFrame* RequestFrame(DecoderParam& param){ return frame; }else if(ret == AVERROR(EAGAIN)){ av_frame_unref(frame); + }else{ + return nullptr; } } }