diff --git a/.cache/clangd/index/Main.cpp.9B5C06CBE98622A0.idx b/.cache/clangd/index/Main.cpp.9B5C06CBE98622A0.idx index 455ce56..e0d763b 100644 Binary files a/.cache/clangd/index/Main.cpp.9B5C06CBE98622A0.idx and b/.cache/clangd/index/Main.cpp.9B5C06CBE98622A0.idx differ diff --git a/.cache/clangd/index/ThumbnailGenerator.cpp.187160649B02AA6F.idx b/.cache/clangd/index/ThumbnailGenerator.cpp.187160649B02AA6F.idx index fbfb737..9f26467 100644 Binary files a/.cache/clangd/index/ThumbnailGenerator.cpp.187160649B02AA6F.idx and b/.cache/clangd/index/ThumbnailGenerator.cpp.187160649B02AA6F.idx differ diff --git a/.cache/clangd/index/ThumbnailGenerator.hpp.1954E12F78148290.idx b/.cache/clangd/index/ThumbnailGenerator.hpp.1954E12F78148290.idx index 18261db..c4ca6c1 100644 Binary files a/.cache/clangd/index/ThumbnailGenerator.hpp.1954E12F78148290.idx and b/.cache/clangd/index/ThumbnailGenerator.hpp.1954E12F78148290.idx differ diff --git a/CMakeLists.txt b/CMakeLists.txt index 34173e3..50300b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,10 @@ pkg_check_modules(LIBAV REQUIRED IMPORTED_TARGET libswscale libavutil ) +# open cv +pkg_check_modules(OPENCV REQUIRED IMPORTED_TARGET + opencv4 +) # compile_commands.json set(CMAKE_EXPORT_COMPILE_COMMANDS ON) @@ -26,4 +30,5 @@ add_executable(ThumbnailGenerator ${source_files}) file (GLOB header_files "${source_dir}/*.hpp") target_include_directories(ThumbnailGenerator PUBLIC ${source_dir}) +target_link_libraries(ThumbnailGenerator PkgConfig::OPENCV) target_link_libraries(ThumbnailGenerator PkgConfig::LIBAV) diff --git a/ThumbnailGenerator b/ThumbnailGenerator index 6cc894a..bb1d8ce 100755 Binary files a/ThumbnailGenerator and b/ThumbnailGenerator differ diff --git a/compile_commands.json b/compile_commands.json index b8b52e3..28f71de 100644 --- a/compile_commands.json +++ b/compile_commands.json @@ -1,12 +1,12 @@ [ { "directory": "/home/talksik/code/cpp_thumbnail_generator/build", - "command": "/usr/bin/c++ -I/home/talksik/code/cpp_thumbnail_generator/./src -g -o CMakeFiles/ThumbnailGenerator.dir/src/Main.cpp.o -c /home/talksik/code/cpp_thumbnail_generator/src/Main.cpp", + "command": "/usr/bin/c++ -I/home/talksik/code/cpp_thumbnail_generator/./src -isystem /usr/include/opencv4 -g -o CMakeFiles/ThumbnailGenerator.dir/src/Main.cpp.o -c /home/talksik/code/cpp_thumbnail_generator/src/Main.cpp", "file": "/home/talksik/code/cpp_thumbnail_generator/src/Main.cpp" }, { "directory": "/home/talksik/code/cpp_thumbnail_generator/build", - "command": "/usr/bin/c++ -I/home/talksik/code/cpp_thumbnail_generator/./src -g -o CMakeFiles/ThumbnailGenerator.dir/src/ThumbnailGenerator.cpp.o -c /home/talksik/code/cpp_thumbnail_generator/src/ThumbnailGenerator.cpp", + "command": "/usr/bin/c++ -I/home/talksik/code/cpp_thumbnail_generator/./src -isystem /usr/include/opencv4 -g -o CMakeFiles/ThumbnailGenerator.dir/src/ThumbnailGenerator.cpp.o -c /home/talksik/code/cpp_thumbnail_generator/src/ThumbnailGenerator.cpp", "file": "/home/talksik/code/cpp_thumbnail_generator/src/ThumbnailGenerator.cpp" } ] \ No newline at end of file diff --git a/src/ThumbnailGenerator.cpp b/src/ThumbnailGenerator.cpp index e9d712c..4d68ea5 100644 --- a/src/ThumbnailGenerator.cpp +++ b/src/ThumbnailGenerator.cpp @@ -1,7 +1,10 @@ #include "include/ThumbnailGenerator.hpp" +#include #include #include #include +#include + extern "C" { #include #include @@ -37,7 +40,8 @@ int ThumbnailGenerator::get_duration_microseconds(std::string input_file_path) { return duration; } -std::string ThumbnailGenerator::generate_thumbnail(std::string input_file_path) { +std::string ThumbnailGenerator::generate_thumbnail(std::string input_file_path, + int frame_number) { std::cout << "generating thumbnail: " << input_file_path << std::endl; // Open input file and allocate format context @@ -95,6 +99,7 @@ std::string ThumbnailGenerator::generate_thumbnail(std::string input_file_path) // Read frames from the video stream while (av_read_frame(format_ctx, &packet) >= 0) { + if (packet.stream_index == video_stream_idx) { // Decode video frame int ret = avcodec_send_packet(codec_ctx, &packet); @@ -106,6 +111,14 @@ std::string ThumbnailGenerator::generate_thumbnail(std::string input_file_path) while (ret >= 0) { ret = avcodec_receive_frame(codec_ctx, frame); + if (codec_ctx->frame_number != frame_number) { + std::cout << "skipping frame: " << codec_ctx->frame_number + << std::endl; + break; + } else { + std::cout << "found frame: " << codec_ctx->frame_number << std::endl; + } + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { break; } else if (ret < 0) { @@ -113,17 +126,42 @@ std::string ThumbnailGenerator::generate_thumbnail(std::string input_file_path) break; } - std::cout << "return value: " << ret << std::endl; std::cout << "frame->format: " << frame->format << std::endl; std::cout << frame->width << "x" << frame->height << std::endl; std::cout << frame->linesize[0] << std::endl; + // cv::Mat convertedMat(frame->height, frame->width, CV_8UC3, + // frame->data[0], frame->linesize[0]); + // + // std::cout << "convertedMat: " << convertedMat.cols << "x" + // << convertedMat.rows << std::endl; + + int width = frame->width; + int height = frame->height; + cv::Mat image(height, width, CV_8UC3); + int cvLinesizes[1]; + cvLinesizes[0] = image.step1(); + SwsContext *conversion = + sws_getContext(width, height, (AVPixelFormat)frame->format, width, + height, AVPixelFormat::AV_PIX_FMT_BGR24, + SWS_FAST_BILINEAR, NULL, NULL, NULL); + sws_scale(conversion, frame->data, frame->linesize, 0, height, + &image.data, cvLinesizes); + sws_freeContext(conversion); + + cv::imshow("Frame", image); + cv::waitKey(25); + + cv::imwrite("output.jpg", image); + // Print basic frame properties std::cout << "Frame " << codec_ctx->frame_number << " (type=" << av_get_picture_type_char(frame->pict_type) << ", size=" << frame->pkt_size << " bytes) pts " << frame->pts << " key_frame " << frame->key_frame << std::endl; + + return "generateThumbnail: " + input_file_path; } } diff --git a/src/include/ThumbnailGenerator.hpp b/src/include/ThumbnailGenerator.hpp index 25fef55..994f2f2 100644 --- a/src/include/ThumbnailGenerator.hpp +++ b/src/include/ThumbnailGenerator.hpp @@ -5,11 +5,12 @@ class ThumbnailGenerator { public: ThumbnailGenerator(); // given a path to a video file, generate a thumbnail - std::string generate_thumbnail(std::string path); + std::string generate_thumbnail(std::string path, int frame_number = 1); // reads and simply prints out information about the video frames void read_video_frames(std::string path); int get_duration_microseconds(std::string path); + private: }; diff --git a/test.jpg b/test.jpg new file mode 100644 index 0000000..82ec57b Binary files /dev/null and b/test.jpg differ