diff --git a/ThumbnailGenerator b/ThumbnailGenerator index b557850..6cc894a 100755 Binary files a/ThumbnailGenerator and b/ThumbnailGenerator differ diff --git a/src/Main.cpp b/src/Main.cpp index 590fd1f..1ddf940 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -25,10 +25,14 @@ int main(int argc, char *argv[]) { std::unique_ptr thumbnailGenerator = std::make_unique(); - int duration = thumbnailGenerator->get_duration(input_file_path); + int duration = thumbnailGenerator->get_duration_microseconds(input_file_path); std::cout << "duration: " << duration << std::endl; // thumbnailGenerator->read_video_frames(input_file_path); + std::string thumbnail_path = + thumbnailGenerator->generate_thumbnail(input_file_path); + std::cout << "thumbnail path: " << thumbnail_path << std::endl; + return 0; } diff --git a/src/ThumbnailGenerator.cpp b/src/ThumbnailGenerator.cpp index 5b6787c..e9d712c 100644 --- a/src/ThumbnailGenerator.cpp +++ b/src/ThumbnailGenerator.cpp @@ -1,5 +1,7 @@ #include "include/ThumbnailGenerator.hpp" #include +#include +#include extern "C" { #include #include @@ -35,9 +37,104 @@ int ThumbnailGenerator::get_duration_microseconds(std::string input_file_path) { return duration; } -std::string ThumbnailGenerator::generate_thumbnail(std::string path) { - std::cout << "generateThumbnail: " << path << std::endl; - return "generateThumbnail: " + path; +std::string ThumbnailGenerator::generate_thumbnail(std::string input_file_path) { + std::cout << "generating thumbnail: " << input_file_path << std::endl; + + // Open input file and allocate format context + AVFormatContext *format_ctx = nullptr; + int ret = avformat_open_input(&format_ctx, input_file_path.c_str(), nullptr, + nullptr); + if (ret < 0) { + std::cerr << "Could not open input file: " << input_file_path << std::endl; + // char buff[256]; + // av_strerror(ret, buff, 256); + // printf(buff); + + std::cerr << "Error: " << ret << std::endl; + AVERROR(ret); + + throw std::runtime_error("Could not open input file"); + } + + // Retrieve stream information + if (avformat_find_stream_info(format_ctx, nullptr) < 0) { + std::cerr << "Could not find stream information" << std::endl; + throw std::runtime_error("Could not find stream information"); + } + + // Find video stream + int video_stream_idx = -1; + for (unsigned int i = 0; i < format_ctx->nb_streams; ++i) { + if (format_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { + video_stream_idx = i; + break; + } + } + + if (video_stream_idx == -1) { + std::cerr << "Could not find video stream" << std::endl; + throw std::runtime_error("Could not find video stream"); + } + + // Get codec parameters and codec context + AVCodecParameters *codecpar = format_ctx->streams[video_stream_idx]->codecpar; + AVCodec *codec = avcodec_find_decoder(codecpar->codec_id); + AVCodecContext *codec_ctx = avcodec_alloc_context3(codec); + avcodec_parameters_to_context(codec_ctx, codecpar); + + // Open codec + if (avcodec_open2(codec_ctx, codec, nullptr) < 0) { + std::cerr << "Could not open codec" << std::endl; + throw std::runtime_error("Could not open codec"); + } + + // Allocate frame and packet + AVFrame *frame = av_frame_alloc(); + AVPacket packet; + av_init_packet(&packet); + + // 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); + if (ret < 0) { + std::cerr << "Error sending packet for decoding" << std::endl; + break; + } + + while (ret >= 0) { + ret = avcodec_receive_frame(codec_ctx, frame); + + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { + break; + } else if (ret < 0) { + std::cerr << "Error during decoding" << std::endl; + 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; + + // 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; + } + } + + av_packet_unref(&packet); + } + + // Free allocated resources + av_frame_free(&frame); + avcodec_free_context(&codec_ctx); + avformat_close_input(&format_ctx); + return "generateThumbnail: " + input_file_path; } void ThumbnailGenerator::read_video_frames(std::string input_file_path) {