diff --git a/main.cc b/main.cc index f246056..5018c6e 100644 --- a/main.cc +++ b/main.cc @@ -2,6 +2,7 @@ #include #include #include +#include #include "util.h" #include "decoder.h" @@ -74,12 +75,12 @@ int InitVideo(SDL_Window*& window, const char* targetFilepath, DecoderParam& dec glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), 0); glEnableVertexAttribArray(0); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), reinterpret_cast(3 * sizeof(float))); glEnableVertexAttribArray(1); glGenTextures(3, openglVideoParam.texs); - for (int i = 0; i < 3; i++) + for (const unsigned int tex : openglVideoParam.texs) { - glBindTexture(GL_TEXTURE_2D, openglVideoParam.texs[i]); + glBindTexture(GL_TEXTURE_2D, tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -93,24 +94,51 @@ int InitVideo(SDL_Window*& window, const char* targetFilepath, DecoderParam& dec shaderService->SetUniform("textureV", 2); return 0; } -void OpenglRender(DecoderParam& decoderParam, const OpenglVideoParam& openglVideoParam, ShaderService* shaderService) + +void RenderPicture(SDL_Window* window, SDL_Renderer* renderer, SDL_Texture* texture) +{ + SDL_SetRenderTarget(renderer, texture); + SDL_SetRenderTarget(renderer, nullptr); + SDL_RenderCopy(renderer, texture, nullptr, nullptr); + SDL_RenderPresent(renderer); +} + +void InitImg(SDL_Window*& window, const char* filepath, SDL_Renderer*& renderer, SDL_Surface*& surface, SDL_Texture*& texture) +{ + const cv::Mat img = cv::imread(filepath); + auto width = img.cols, height = img.rows; + cv::Mat target; + SDL_Rect rect; + SDL_GetDisplayBounds(0, &rect); + width = width > rect.w ? rect.w - 100 : width; + height = height > rect.h ? rect.h - 100 : height; + const cv::Size size{ width, height }; + cv::resize(img, target, size, 0, 0, cv::INTER_LINEAR_EXACT); + window = SDL_CreateWindow("mp", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_SHOWN); + surface = SDL_CreateRGBSurfaceWithFormat(0, width, height, 24, SDL_PIXELFORMAT_RGB24); + memcpy(surface->pixels, target.data, static_cast(width) * height * target.channels()); + renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); + texture = SDL_CreateTextureFromSurface(renderer, surface); +} + +void OpenglRenderVideo(DecoderParam& decoderParam, const OpenglVideoParam& openglVideoParam, ShaderService* shaderService) { auto frame = RequestFrame(decoderParam); if (frame == nullptr) return; // TODO: TIMER glBindTexture(GL_TEXTURE_2D, openglVideoParam.texs[0]); - glPixelStoref(GL_UNPACK_ROW_LENGTH, frame->linesize[0]); + glPixelStoref(GL_UNPACK_ROW_LENGTH, static_cast(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]); + glPixelStoref(GL_UNPACK_ROW_LENGTH, static_cast(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]); + glPixelStoref(GL_UNPACK_ROW_LENGTH, static_cast(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]); av_frame_free(&frame); @@ -118,14 +146,14 @@ void OpenglRender(DecoderParam& decoderParam, const OpenglVideoParam& openglVide shaderService->Use(); glBindVertexArray(openglVideoParam.VAO); - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr); } int main(int argc, char** const argv) { // Check File const char* targetFilepath = argv[1]; - if (targetFilepath == nullptr || !std::filesystem::exists(targetFilepath)) + if (targetFilepath == nullptr || !exists(targetFilepath)) { cout << "File Not Exist\n"; return 0; @@ -133,7 +161,7 @@ int main(int argc, char** const argv) const FileType fileType = Util::GetFileType(targetFilepath); if (fileType == FileType::ERRORTYPE) { - cout << "unsupport file type\n"; + cout << "unsupported file type\n"; return 0; } @@ -144,6 +172,9 @@ int main(int argc, char** const argv) DecoderParam decoderParam{}; OpenglVideoParam openglVideoParam{}; ShaderService* shaderService = nullptr; + SDL_Surface* surface = nullptr; + SDL_Renderer* renderer = nullptr; + SDL_Texture* texture = nullptr; double framerate = .0f; if (SDL_Init(SDL_INIT_EVERYTHING) < 0) { @@ -155,19 +186,20 @@ int main(int argc, char** const argv) case FileType::VIDEO: { InitVideo(window, targetFilepath, decoderParam, openglVideoParam, shaderService); - auto stream_frame_rate = decoderParam.fmtCtx->streams[decoderParam.videoStreamIndex]->avg_frame_rate; + const auto stream_frame_rate = decoderParam.fmtCtx->streams[decoderParam.videoStreamIndex]->avg_frame_rate; framerate = static_cast(stream_frame_rate.den) / stream_frame_rate.num; break; } case FileType::IMG: { + InitImg(window, targetFilepath, renderer, surface, texture); break; } case FileType::MUSIC: { break; } - default: + case FileType::ERRORTYPE: return -1; } @@ -184,13 +216,15 @@ int main(int argc, char** const argv) switch (event.key.keysym.scancode) { case SDL_SCANCODE_ESCAPE: - return -1; + quit = true; + break; default: break; } break; case SDL_QUIT: - return -1; + quit = true; + break; default: break; } @@ -200,12 +234,14 @@ int main(int argc, char** const argv) switch (fileType) { case FileType::VIDEO: - OpenglRender(decoderParam, openglVideoParam, shaderService); + OpenglRenderVideo(decoderParam, openglVideoParam, shaderService); SDL_GL_SwapWindow(window); std::this_thread::sleep_until(current_time + std::chrono::milliseconds(static_cast(framerate * 1000))); current_time = std::chrono::system_clock::now(); break; - + case FileType::IMG: + RenderPicture(window, renderer, texture); + break; default: break; } diff --git a/video/ocean.jpg b/video/ocean.jpg new file mode 100644 index 0000000..703d774 Binary files /dev/null and b/video/ocean.jpg differ