generate thumbnial with opencv nicely
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -12,6 +12,10 @@ pkg_check_modules(LIBAV REQUIRED IMPORTED_TARGET
|
|||||||
libswscale
|
libswscale
|
||||||
libavutil
|
libavutil
|
||||||
)
|
)
|
||||||
|
# open cv
|
||||||
|
pkg_check_modules(OPENCV REQUIRED IMPORTED_TARGET
|
||||||
|
opencv4
|
||||||
|
)
|
||||||
|
|
||||||
# compile_commands.json
|
# compile_commands.json
|
||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
@@ -26,4 +30,5 @@ add_executable(ThumbnailGenerator ${source_files})
|
|||||||
file (GLOB header_files "${source_dir}/*.hpp")
|
file (GLOB header_files "${source_dir}/*.hpp")
|
||||||
target_include_directories(ThumbnailGenerator PUBLIC ${source_dir})
|
target_include_directories(ThumbnailGenerator PUBLIC ${source_dir})
|
||||||
|
|
||||||
|
target_link_libraries(ThumbnailGenerator PkgConfig::OPENCV)
|
||||||
target_link_libraries(ThumbnailGenerator PkgConfig::LIBAV)
|
target_link_libraries(ThumbnailGenerator PkgConfig::LIBAV)
|
||||||
|
|||||||
Binary file not shown.
@@ -1,12 +1,12 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"directory": "/home/talksik/code/cpp_thumbnail_generator/build",
|
"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"
|
"file": "/home/talksik/code/cpp_thumbnail_generator/src/Main.cpp"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"directory": "/home/talksik/code/cpp_thumbnail_generator/build",
|
"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"
|
"file": "/home/talksik/code/cpp_thumbnail_generator/src/ThumbnailGenerator.cpp"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
#include "include/ThumbnailGenerator.hpp"
|
#include "include/ThumbnailGenerator.hpp"
|
||||||
|
#include <bits/types/FILE.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <libavutil/pixdesc.h>
|
#include <libavutil/pixdesc.h>
|
||||||
#include <libavutil/pixfmt.h>
|
#include <libavutil/pixfmt.h>
|
||||||
|
#include <opencv4/opencv2/opencv.hpp>
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <libavcodec/avcodec.h>
|
#include <libavcodec/avcodec.h>
|
||||||
#include <libavformat/avformat.h>
|
#include <libavformat/avformat.h>
|
||||||
@@ -37,7 +40,8 @@ int ThumbnailGenerator::get_duration_microseconds(std::string input_file_path) {
|
|||||||
return duration;
|
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;
|
std::cout << "generating thumbnail: " << input_file_path << std::endl;
|
||||||
|
|
||||||
// Open input file and allocate format context
|
// 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
|
// Read frames from the video stream
|
||||||
while (av_read_frame(format_ctx, &packet) >= 0) {
|
while (av_read_frame(format_ctx, &packet) >= 0) {
|
||||||
|
|
||||||
if (packet.stream_index == video_stream_idx) {
|
if (packet.stream_index == video_stream_idx) {
|
||||||
// Decode video frame
|
// Decode video frame
|
||||||
int ret = avcodec_send_packet(codec_ctx, &packet);
|
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) {
|
while (ret >= 0) {
|
||||||
ret = avcodec_receive_frame(codec_ctx, frame);
|
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) {
|
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
|
||||||
break;
|
break;
|
||||||
} else if (ret < 0) {
|
} else if (ret < 0) {
|
||||||
@@ -113,17 +126,42 @@ std::string ThumbnailGenerator::generate_thumbnail(std::string input_file_path)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "return value: " << ret << std::endl;
|
|
||||||
std::cout << "frame->format: " << frame->format << std::endl;
|
std::cout << "frame->format: " << frame->format << std::endl;
|
||||||
std::cout << frame->width << "x" << frame->height << std::endl;
|
std::cout << frame->width << "x" << frame->height << std::endl;
|
||||||
std::cout << frame->linesize[0] << 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
|
// Print basic frame properties
|
||||||
std::cout << "Frame " << codec_ctx->frame_number
|
std::cout << "Frame " << codec_ctx->frame_number
|
||||||
<< " (type=" << av_get_picture_type_char(frame->pict_type)
|
<< " (type=" << av_get_picture_type_char(frame->pict_type)
|
||||||
<< ", size=" << frame->pkt_size << " bytes) pts "
|
<< ", size=" << frame->pkt_size << " bytes) pts "
|
||||||
<< frame->pts << " key_frame " << frame->key_frame
|
<< frame->pts << " key_frame " << frame->key_frame
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
|
return "generateThumbnail: " + input_file_path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,12 @@ class ThumbnailGenerator {
|
|||||||
public:
|
public:
|
||||||
ThumbnailGenerator();
|
ThumbnailGenerator();
|
||||||
// given a path to a video file, generate a thumbnail
|
// 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
|
// reads and simply prints out information about the video frames
|
||||||
void read_video_frames(std::string path);
|
void read_video_frames(std::string path);
|
||||||
|
|
||||||
int get_duration_microseconds(std::string path);
|
int get_duration_microseconds(std::string path);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user