diff options
author | aneejit1 <aneejit1@gmail.com> | 2022-05-17 12:02:27 +0000 |
---|---|---|
committer | aneejit1 <aneejit1@gmail.com> | 2022-05-19 14:23:06 +0000 |
commit | e71518b16cb4507712e2bf69e4902fc1689d9995 (patch) | |
tree | ae70747582b03ef2c37e05ec85603e1e00aca965 /k9author/k9avidecode.cpp | |
parent | 67d45db6d67f3d71534f214666c8fb85b4d6fa2b (diff) | |
download | k9copy-e71518b16cb4507712e2bf69e4902fc1689d9995.tar.gz k9copy-e71518b16cb4507712e2bf69e4902fc1689d9995.zip |
Implement ffmpeg version 5 support
Version 5.0 of ffmpeg drops a load of deprecated API functions causing
k9copy to fail its build. The necessary changes have been made to
enable k9copy to build against ffmpeg 5.0 as well as retaining support
for older versions. Support for older pre-0.5.1 versions has been
dropped as has runtime linking of the ffmpeg libraries. libswscale is
now mandatory.
Signed-off-by: aneejit1 <aneejit1@gmail.com>
Diffstat (limited to 'k9author/k9avidecode.cpp')
-rw-r--r-- | k9author/k9avidecode.cpp | 315 |
1 files changed, 117 insertions, 198 deletions
diff --git a/k9author/k9avidecode.cpp b/k9author/k9avidecode.cpp index d51ec9a..107f9ae 100644 --- a/k9author/k9avidecode.cpp +++ b/k9author/k9avidecode.cpp @@ -12,22 +12,13 @@ #include "config.h" #include "k9avidecode.h" -#ifdef OLD_FFMPEG -#include <ffmpeg/avcodec.h> -#endif -#ifdef NEW_FFMPEG -#include <libavcodec/avcodec.h> -#include <libavformat/avformat.h> -#include <libavutil/avutil.h> -#endif - // This is probably the incorrect revision for when CODEC_TYPE_VIDEO was removed // Please update the comparison below if you know the exact revision that CODEC_TYPE_VIDEO was removed in! #if LIBAVCODEC_VERSION_INT < (AV_VERSION_INT(52,72,2)) #define AVMEDIA_TYPE_VIDEO CODEC_TYPE_VIDEO #endif -#if !defined(NEW_FFMPEG) || LIBAVUTIL_VERSION_INT < AV_VERSION_INT(51,42,0) +#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(51,42,0) #define AV_PIX_FMT_RGB24 PIX_FMT_RGB24 #endif @@ -37,125 +28,17 @@ #include <cstdlib> #include "ac.h" -void *CodecHandle=0; -void *FormatHandle=0; -void *UtilHandle=0; -void *SwscaleHandle=0; -int glibref=0; - -#ifdef NEW_FFMPEG -void av_free_packet_internal(AVPacket *pkt) -{ - if (pkt) { -# if LIBAVCODEC_VERSION_INT < (AV_VERSION_INT(56,0,0)) - if (pkt->destruct) pkt->destruct(pkt); -# endif - pkt->data = NULL; pkt->size = 0; - } -} -#endif -#ifdef HAVE_SWSCALE -#include "libswscale/swscale.h" static int sws_flags = SWS_BICUBIC; -#endif k9AviDecode::k9AviDecode(TQObject *parent, const char *name) : TQObject(parent, name) { - if (glibref==0) { - CodecHandle=dlopen("libavcodec.so",RTLD_LAZY | RTLD_GLOBAL); - FormatHandle=dlopen("libavformat.so",RTLD_LAZY | RTLD_GLOBAL); - UtilHandle=dlopen("libavutil.so",RTLD_LAZY | RTLD_GLOBAL); -# ifdef HAVE_SWSCALE - SwscaleHandle=dlopen("libswscale.so",RTLD_LAZY); - if (SwscaleHandle==0) - SwscaleHandle=dlopen("libswscale.so.2",RTLD_LAZY); -# endif - } - if (!CodecHandle) { - m_error =i18n("Cannot open then library %1").arg("libavcodec"); - return; - } - if (!FormatHandle) { - m_error =i18n("Cannot open then library %1").arg("libavformat"); - return; - } -# if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(51, 33, 0) - if (!UtilHandle) { - m_error =i18n("Cannot open then library %1").arg("libavutil"); - return; - } -# endif -# ifdef HAVE_SWSCALE - if (!SwscaleHandle) { - m_error =i18n("Cannot open the library %1").arg("libswscale"); - } -# endif - m_error=""; - av_register_all = (av_register_all_t)dlsym(FormatHandle,"av_register_all"); -# if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53, 2, 0) - avformat_open_input = (avformat_open_input_t)dlsym(FormatHandle,"avformat_open_input"); -# else - av_open_input_file = (av_open_input_file_t)dlsym(FormatHandle,"av_open_input_file"); -# endif -# if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53, 6, 0) - avformat_find_stream_info = (avformat_find_stream_info_t)dlsym(FormatHandle,"avformat_find_stream_info"); -# else - av_find_stream_info = (av_find_stream_info_t)dlsym(FormatHandle,"av_find_stream_info"); -# endif - avcodec_find_decoder =(avcodec_find_decoder_t) dlsym(CodecHandle,"avcodec_find_decoder"); -# if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53, 8, 0) - avcodec_open2 = (avcodec_open2_t)dlsym(CodecHandle,"avcodec_open2"); -# else - avcodec_open = (avcodec_open_t)dlsym(CodecHandle,"avcodec_open"); -# endif - avcodec_alloc_frame = (avcodec_alloc_frame_t)dlsym(CodecHandle,"avcodec_alloc_frame"); - avpicture_get_size = (avpicture_get_size_t)dlsym(CodecHandle,"avpicture_get_size"); - av_malloc = (av_malloc_t)dlsym(CodecHandle,"av_malloc"); - avpicture_fill = (avpicture_fill_t)dlsym(CodecHandle,"avpicture_fill"); - av_read_frame = (av_read_frame_t)dlsym(FormatHandle,"av_read_frame"); -# if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 23, 0) - avcodec_decode_video2 = (avcodec_decode_video2_t)dlsym(CodecHandle,"avcodec_decode_video2"); -# else - avcodec_decode_video = (avcodec_decode_video_t)dlsym(CodecHandle,"avcodec_decode_video"); -# endif -# ifndef HAVE_SWSCALE - img_convert = (img_convert_t)dlsym(CodecHandle,"img_convert"); - //if img_convert is null (deprecated in ffmpeg), we need libswscale - if (!img_convert) { - m_error = i18n("Cannot open the library %1").arg("libswscale"); - return; - } -# endif - av_free = (av_free_t)dlsym(CodecHandle,"av_free"); - av_free_packet = (av_free_packet_t)dlsym(CodecHandle,"av_free_packet"); - if (av_free_packet==0) - av_free_packet=av_free_packet_internal; - avcodec_close = (avcodec_close_t)dlsym(FormatHandle,"avcodec_close"); -# if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53, 17, 0) - avformat_close_input = (avformat_close_input_t)dlsym(FormatHandle,"avformat_close_input"); -# else - av_close_input_file = (av_close_input_file_t)dlsym(FormatHandle,"av_close_input_file"); -# endif - av_seek_frame=(av_seek_frame_t)dlsym(FormatHandle,"av_seek_frame"); - av_rescale_q=(av_rescale_q_t)dlsym(FormatHandle,"av_rescale_q"); - avcodec_flush_buffers=(avcodec_flush_buffers_t)dlsym(CodecHandle,"avcodec_flush_buffers"); -# ifdef HAVE_SWSCALE - sws_freeContext= (sws_freeContext_t)dlsym(SwscaleHandle,"sws_freeContext"); - sws_getContext=(sws_getContext_t)dlsym(SwscaleHandle,"sws_getContext"); - sws_scale= (sws_scale_t)dlsym(SwscaleHandle,"sws_scale"); -# endif - -# if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(51, 33, 0) - av_gettime=(av_gettime_t)dlsym(UtilHandle,"av_gettime"); -# else - av_gettime=(av_gettime_t)dlsym(FormatHandle,"av_gettime"); -# endif + +#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(58,9,100) av_register_all(); +#endif m_opened=false; - glibref++; - m_FormatCtx = NULL; m_CodecCtx = NULL; m_Codec = NULL; @@ -168,20 +51,6 @@ k9AviDecode::k9AviDecode(TQObject *parent, const char *name) k9AviDecode::~k9AviDecode() { if (m_opened) close(); - glibref--; - if (glibref==0) { - dlclose(FormatHandle); - dlclose(CodecHandle); - if(UtilHandle) { - dlclose(UtilHandle); - } -# ifdef HAVE_SWSCALE - if (SwscaleHandle) { - dlclose(CodecHandle); - } -# endif - } - } @@ -194,33 +63,36 @@ bool k9AviDecode::open(const TQString & _fileName) { close(); // Open video file - if ( -# if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53, 2, 0) - avformat_open_input(&m_FormatCtx, _fileName.utf8(), NULL, NULL)!=0 -# else - av_open_input_file(&m_FormatCtx, _fileName.utf8(), NULL, 0, NULL)!=0 -# endif - ) { +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53, 2, 0) + if (avformat_open_input(&m_FormatCtx, _fileName.utf8(), NULL, NULL)!=0) +#else + if (av_open_input_file(&m_FormatCtx, _fileName.utf8(), NULL, 0, NULL)!=0) +#endif + { m_error=i18n("Couldn't open the file %1").arg(_fileName); return false; // Couldn't open file} } // Retrieve stream information - if ( -# if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53, 6, 0) - avformat_find_stream_info(m_FormatCtx, NULL)<0 -# else - av_find_stream_info(m_FormatCtx)<0 -# endif - ) { +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53, 6, 0) + if (avformat_find_stream_info(m_FormatCtx, NULL)<0) +#else + if (av_find_stream_info(m_FormatCtx)<0) +#endif + { m_error =i18n("Couldn't find stream information"); return false; // Couldn't find stream information } - int i; + unsigned int i; // Find the first video stream m_videoStream=-1; for (i=0; i<m_FormatCtx->nb_streams; i++) - if (m_FormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) { +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 33, 100) + if (m_FormatCtx->streams[i]->codecpar->codec_type==AVMEDIA_TYPE_VIDEO) +#else + if (m_FormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) +#endif + { m_videoStream=i; break; } @@ -229,34 +101,56 @@ bool k9AviDecode::open(const TQString & _fileName) { return false; // Didn't find a video stream } - // Get a pointer to the codec context for the video stream - m_CodecCtx=m_FormatCtx->streams[m_videoStream]->codec; - - // Find the decoder for the video stream - m_Codec=avcodec_find_decoder(m_CodecCtx->codec_id); +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 33, 100) + m_Codec=(AVCodec *)avcodec_find_decoder(m_FormatCtx->streams[m_videoStream]->codecpar->codec_id); +#else + m_Codec=(AVCodec *)avcodec_find_decoder(m_FormatCtx->streams[m_videoStream]->codec->codec_id); +#endif if (m_Codec==NULL) { m_error=i18n("Unsupported codec"); return false; // Codec not found } + +// Get/allocate a pointer to the codec context for the video stream +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 33, 100) + m_CodecCtx = avcodec_alloc_context3(m_Codec); + if (m_CodecCtx) { + avcodec_parameters_to_context(m_CodecCtx, m_FormatCtx->streams[m_videoStream]->codecpar); + } + else { + m_error=i18n("Failed to allocate a codec context"); + return false; + } +#else + m_CodecCtx=m_FormatCtx->streams[m_videoStream]->codec; +#endif + // Open codec - if ( -# if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53, 8, 0) - avcodec_open2(m_CodecCtx, m_Codec, NULL)<0 -# else - avcodec_open(m_CodecCtx, m_Codec)<0 -# endif - ) { +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53, 8, 0) + if (avcodec_open2(m_CodecCtx, m_Codec, NULL)<0) +#else + if (avcodec_open(m_CodecCtx, m_Codec)<0) +#endif + { m_error =i18n("Could'nt open the codec"); return false; // Could not open codec } // Allocate video frame +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 45, 101) + m_Frame=av_frame_alloc(); +#else m_Frame=avcodec_alloc_frame(); +#endif // Allocate an AVFrame structure +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 45, 101) + m_FrameRGB=av_frame_alloc(); +#else m_FrameRGB=avcodec_alloc_frame(); +#endif if (m_FrameRGB==NULL) { m_error =i18n ("Unable to allocate memory for frames"); return false; @@ -265,15 +159,25 @@ bool k9AviDecode::open(const TQString & _fileName) { int numBytes; // Determine required buffer size and allocate buffer +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 24, 100) + numBytes=av_image_get_buffer_size(AV_PIX_FMT_RGB24, m_CodecCtx->width, + m_CodecCtx->height, 1); +#else numBytes=avpicture_get_size(AV_PIX_FMT_RGB24, m_CodecCtx->width, m_CodecCtx->height); +#endif m_buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t)); // Assign appropriate parts of buffer to image planes in pFrameRGB // Note that pFrameRGB is an AVFrame, but AVFrame is a superset // of AVPicture +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 24, 100) + av_image_fill_arrays(m_FrameRGB->data, m_FrameRGB->linesize, m_buffer, + AV_PIX_FMT_RGB24, m_CodecCtx->width, m_CodecCtx->height, 1); +#else avpicture_fill((AVPicture *)m_FrameRGB, m_buffer, AV_PIX_FMT_RGB24, m_CodecCtx->width, m_CodecCtx->height); +#endif m_duration=(double)m_FormatCtx->duration / AV_TIME_BASE; m_opened=true; @@ -296,60 +200,70 @@ void k9AviDecode::readFrame(double _seconds) { int res=av_seek_frame(m_FormatCtx, m_videoStream, fspos, AVSEEK_FLAG_BACKWARD ); avcodec_flush_buffers(m_CodecCtx); int frameFinished=0; - AVPacket packet; + AVPacket *packet; + +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 12, 100) + packet = av_packet_alloc(); +#else + AVPacket _packet; + av_init_packet(&_packet); + packet = &_packet; +#endif -# ifdef HAVE_SWSCALE struct SwsContext *toRGB_convert_ctx; -# endif bool bFound=false; - while (av_read_frame(m_FormatCtx, &packet)>=0 && !bFound) { + while (av_read_frame(m_FormatCtx, packet)>=0 && !bFound) { // Is this a packet from the video stream? - if (packet.stream_index==m_videoStream) { + if (packet->stream_index==m_videoStream) { // Decode video frame -# if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 23, 0) - avcodec_decode_video2(m_CodecCtx, m_Frame, &frameFinished, &packet); -# else +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 37, 100) + int ret = avcodec_receive_frame(m_CodecCtx, m_Frame); + if (ret == 0) + frameFinished = 1; + else if (ret == AVERROR(EAGAIN)) + ret = 0; + if (ret == 0) + ret = avcodec_send_packet(m_CodecCtx, packet); +#elif LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 23, 0) + avcodec_decode_video2(m_CodecCtx, m_Frame, &frameFinished, packet); +#else avcodec_decode_video(m_CodecCtx, m_Frame, &frameFinished, - packet.data, packet.size); -# endif + packet->data, packet->size); +#endif // Did we get a video frame? if (frameFinished) { -// if (m_Frame->pts >=fspos) - int64_t cur_dts=fspos; -# if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(54, 2, 0) - cur_dts= packet.dts; -# else - if (m_FormatCtx->cur_st) - cur_dts= m_FormatCtx->cur_st->cur_dts; -# endif + int64_t cur_dts=fspos; +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(54, 2, 0) + cur_dts = packet->dts; +#else + if (m_FormatCtx->cur_st) + cur_dts = m_FormatCtx->cur_st->cur_dts; +#endif if (cur_dts >=fspos) { bFound=true; -# ifndef HAVE_SWSCALE - // Convert the image from its native format to RGB - img_convert((AVPicture *)m_FrameRGB, AV_PIX_FMT_RGB24, - (AVPicture*)m_Frame, m_CodecCtx->pix_fmt, - m_CodecCtx->width, m_CodecCtx->height); - - // convert frame to TQImage - SaveFrame(m_FrameRGB, m_CodecCtx->width, - m_CodecCtx->height); -# else toRGB_convert_ctx=sws_getContext(m_CodecCtx->width, m_CodecCtx->height, m_CodecCtx->pix_fmt, m_CodecCtx->width, m_CodecCtx->height, AV_PIX_FMT_RGB24, sws_flags,NULL,NULL,NULL); - sws_scale(toRGB_convert_ctx, m_Frame->data, m_Frame->linesize, 0, m_CodecCtx->height, m_FrameRGB->data,m_FrameRGB->linesize); + sws_scale(toRGB_convert_ctx, m_Frame->data, m_Frame->linesize, 0, m_CodecCtx->height, m_FrameRGB->data,m_FrameRGB->linesize); // convert frame to QImage SaveFrame(m_FrameRGB, m_CodecCtx->width, m_CodecCtx->height); sws_freeContext(toRGB_convert_ctx); -# endif } } } - // Free the packet that was allocated by av_read_frame - av_free_packet(&packet); +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 25, 100) + // Unreference the packet from av_read_frame + av_packet_unref(packet); +#else + // Free the packet from av_read_frame + av_free_packet(packet); +#endif } +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 12, 100) + av_packet_free(&packet); +#endif } void k9AviDecode::SaveFrame(AVFrame *pFrame, int width, int height) { @@ -380,11 +294,16 @@ void k9AviDecode::close() { avcodec_close(m_CodecCtx); // Close the video file -# if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53, 17, 0) +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53, 17, 0) avformat_close_input(&m_FormatCtx); -# else +#else av_close_input_file(m_FormatCtx); -# endif +#endif + +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 63, 100) + avcodec_free_context(&m_CodecCtx); +#endif + m_opened=false; } } |