author | Antonio Rojas
<arojas@archlinux.org> 2022-01-26 18:36:03 UTC |
committer | Antonio Rojas
<arojas@archlinux.org> 2022-01-26 18:36:03 UTC |
parent | e7857a2a12dd07ad7a3d0c5a6588057a743c6fbb |
PKGBUILD | +9 | -3 |
ffmpeg5.patch | +123 | -0 |
diff --git a/PKGBUILD b/PKGBUILD index 2c0da6a..1108952 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -3,7 +3,7 @@ pkgname=ffmpegthumbnailer pkgver=2.2.2 -pkgrel=2 +pkgrel=3 pkgdesc="Lightweight video thumbnailer that can be used by file managers." url="https://github.com/dirkvdb/ffmpegthumbnailer" license=('GPL2') @@ -11,8 +11,14 @@ arch=('x86_64') depends=('ffmpeg' 'libjpeg' 'libpng') makedepends=('cmake') optdepends=('gvfs: support for gio uris') -source=("https://github.com/dirkvdb/$pkgname/archive/$pkgver.tar.gz") -sha1sums=('1b35a8afc94edd9135baef9e5259a40b4c0d4d79') +source=(https://github.com/dirkvdb/$pkgname/archive/$pkgver/$pkgname-$pkgver.tar.gz + ffmpeg5.patch) +sha1sums=('1b35a8afc94edd9135baef9e5259a40b4c0d4d79' + 'cb873fa82409180cee57cc3f2705e81bd0a27888') + +prepare() { + patch -d $pkgname-$pkgver -p1 < ffmpeg5.patch # Fix build with FFmpeg 5 +} build() { cd "${srcdir}/${pkgname}-${pkgver}" diff --git a/ffmpeg5.patch b/ffmpeg5.patch new file mode 100644 index 0000000..552698f --- /dev/null +++ b/ffmpeg5.patch @@ -0,0 +1,123 @@ +diff --git a/libffmpegthumbnailer/moviedecoder.cpp b/libffmpegthumbnailer/moviedecoder.cpp +index 290e212..fd0a9e1 100644 +--- a/libffmpegthumbnailer/moviedecoder.cpp ++++ b/libffmpegthumbnailer/moviedecoder.cpp +@@ -70,8 +70,6 @@ MovieDecoder::~MovieDecoder() + + void MovieDecoder::initialize(const string& filename, bool preferEmbeddedMetadata) + { +- av_register_all(); +- avcodec_register_all(); + avformat_network_init(); + + string inputFile = filename == "-" ? "pipe:" : filename; +@@ -152,7 +150,7 @@ int32_t MovieDecoder::findPreferedVideoStream(bool preferEmbeddedMetadata) + for (unsigned int i = 0; i < m_pFormatContext->nb_streams; ++i) + { + AVStream *stream = m_pFormatContext->streams[i]; +- auto ctx = m_pFormatContext->streams[i]->codec; ++ auto ctx = m_pFormatContext->streams[i]->codecpar; + if (ctx->codec_type == AVMEDIA_TYPE_VIDEO) + { + if (!preferEmbeddedMetadata || !isStillImageCodec(ctx->codec_id)) +@@ -203,8 +201,9 @@ void MovieDecoder::initializeVideo(bool preferEmbeddedMetadata) + } + + m_pVideoStream = m_pFormatContext->streams[m_VideoStream]; +- m_pVideoCodecContext = m_pVideoStream->codec; +- m_pVideoCodec = avcodec_find_decoder(m_pVideoCodecContext->codec_id); ++ m_pVideoCodec = avcodec_find_decoder(m_pVideoStream->codecpar->codec_id); ++ m_pVideoCodecContext = avcodec_alloc_context3(m_pVideoCodec); ++ avcodec_parameters_to_context(m_pVideoCodecContext, m_pVideoStream->codecpar); + + if (m_pVideoCodec == nullptr) + { +@@ -391,8 +390,6 @@ void MovieDecoder::initializeFilterGraph(const AVRational& timeBase, const std:: + auto del = [] (AVBufferSinkParams* p) { av_freep(p); }; + std::unique_ptr<AVBufferSinkParams, decltype(del)> buffersinkParams(av_buffersink_params_alloc(), del); + +- avfilter_register_all(); +- + m_pFilterGraph = avfilter_graph_alloc(); + assert(m_pFilterGraph); + +@@ -500,7 +497,7 @@ void MovieDecoder::seek(int timeInSeconds) + } + + checkRc(av_seek_frame(m_pFormatContext, -1, timestamp, 0), "Seeking in video failed"); +- avcodec_flush_buffers(m_pFormatContext->streams[m_VideoStream]->codec); ++ avcodec_flush_buffers(m_pVideoCodecContext); + + int keyFrameAttempts = 0; + bool gotFrame = 0; +@@ -545,6 +542,30 @@ void MovieDecoder::decodeVideoFrame() + } + } + ++// The flush packet is a non-NULL packet with size 0 and data NULL ++int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *pkt) ++{ ++ int ret; ++ ++ *got_frame = 0; ++ ++ if (pkt) { ++ ret = avcodec_send_packet(avctx, pkt); ++ // In particular, we don't expect AVERROR(EAGAIN), because we read all ++ // decoded frames with avcodec_receive_frame() until done. ++ if (ret < 0) ++ return ret == AVERROR_EOF ? 0 : ret; ++ } ++ ++ ret = avcodec_receive_frame(avctx, frame); ++ if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) ++ return ret; ++ if (ret >= 0) ++ *got_frame = 1; ++ ++ return 0; ++} ++ + bool MovieDecoder::decodeVideoPacket() + { + if (m_pPacket->stream_index != m_VideoStream) +@@ -554,13 +575,24 @@ bool MovieDecoder::decodeVideoPacket() + + av_frame_unref(m_pFrame); + +- int frameFinished; ++ int frameFinished = 0; ++ int bytesDecoded; + +- int bytesDecoded = avcodec_decode_video2(m_pVideoCodecContext, m_pFrame, &frameFinished, m_pPacket); ++ if (m_pPacket) { ++ bytesDecoded = avcodec_send_packet(m_pVideoCodecContext, m_pPacket); ++ if (bytesDecoded < 0 && bytesDecoded != AVERROR_EOF) ++ { ++ throw logic_error("Failed to decode video frame: bytesDecoded < 0"); ++ } ++ } ++ ++ bytesDecoded = avcodec_receive_frame(m_pVideoCodecContext, m_pFrame); + if (bytesDecoded < 0) + { + throw logic_error("Failed to decode video frame: bytesDecoded < 0"); + } ++ else ++ frameFinished = 1; + + return frameFinished > 0; + } +diff --git a/libffmpegthumbnailer/moviedecoder.h b/libffmpegthumbnailer/moviedecoder.h +index 3ef5f12..fb6add2 100644 +--- a/libffmpegthumbnailer/moviedecoder.h ++++ b/libffmpegthumbnailer/moviedecoder.h +@@ -78,7 +78,7 @@ private: + int m_VideoStream; + AVFormatContext* m_pFormatContext; + AVCodecContext* m_pVideoCodecContext; +- AVCodec* m_pVideoCodec; ++ const AVCodec* m_pVideoCodec; + AVFilterGraph* m_pFilterGraph; + AVFilterContext* m_pFilterSource; + AVFilterContext* m_pFilterSink;