diff options
author | Alexis Ballier <aballier@gentoo.org> | 2013-07-26 15:48:51 -0400 |
---|---|---|
committer | Alexis Ballier <aballier@gentoo.org> | 2013-08-01 16:12:01 -0400 |
commit | 156501303b0175a6cf65fb597528e0e50eaf4aeb (patch) | |
tree | 5d5629bef6aebbdb3361528bfe2fed9ac5676598 | |
parent | ea3b8ccf7aa1cdef19890030341dedacdfd718e8 (diff) |
Switch to the avframe based API for libavfilter when it is available.
The old API is deprecated and the new code is simpler and saves a memcopy.
Also, use the AVFrame values instead of the codec context for DVDVideoCodecFFmpeg::GetPicture.
-rw-r--r-- | lib/DllAvFilter.h | 36 | ||||
-rw-r--r-- | xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp | 50 | ||||
-rw-r--r-- | xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h | 4 |
3 files changed, 85 insertions, 5 deletions
diff --git a/lib/DllAvFilter.h b/lib/DllAvFilter.h index 7929503bf4..59f579a508 100644 --- a/lib/DllAvFilter.h +++ b/lib/DllAvFilter.h @@ -60,6 +60,10 @@ extern "C" { #define LIBAVFILTER_FROM_LIBAV #endif +#if ( defined(LIBAVFILTER_FROM_FFMPEG) && LIBAVFILTER_VERSION_INT >= AV_VERSION_INT(3,43,100)) || \ + ( defined(LIBAVFILTER_FROM_LIBAV) && LIBAVFILTER_VERSION_INT >= AV_VERSION_INT(3,5,0)) +#define LIBAVFILTER_AVFRAME_BASED +#endif #include "threads/SingleLock.h" @@ -84,11 +88,19 @@ public: #else virtual int av_vsrc_buffer_add_frame(AVFilterContext *buffer_filter, AVFrame *frame, int flags)=0; #endif +#if !defined(LIBAVFILTER_AVFRAME_BASED) virtual void avfilter_unref_buffer(AVFilterBufferRef *ref)=0; +#endif virtual int avfilter_link(AVFilterContext *src, unsigned srcpad, AVFilterContext *dst, unsigned dstpad)=0; +#if defined(LIBAVFILTER_AVFRAME_BASED) + virtual int av_buffersink_get_frame(AVFilterContext *ctx, AVFrame *frame) = 0; +#else virtual int av_buffersink_get_buffer_ref(AVFilterContext *buffer_sink, AVFilterBufferRef **bufref, int flags)=0; +#endif virtual AVBufferSinkParams *av_buffersink_params_alloc()=0; +#if !defined(LIBAVFILTER_AVFRAME_BASED) virtual int av_buffersink_poll_frame(AVFilterContext *ctx)=0; +#endif }; #if (defined USE_EXTERNAL_FFMPEG) || (defined TARGET_DARWIN) @@ -142,11 +154,19 @@ public: #else virtual int av_vsrc_buffer_add_frame(AVFilterContext *buffer_filter, AVFrame *frame, int flags) { return ::av_vsrc_buffer_add_frame(buffer_filter, frame, flags); } #endif +#if !defined(LIBAVFILTER_AVFRAME_BASED) virtual void avfilter_unref_buffer(AVFilterBufferRef *ref) { ::avfilter_unref_buffer(ref); } +#endif virtual int avfilter_link(AVFilterContext *src, unsigned srcpad, AVFilterContext *dst, unsigned dstpad) { return ::avfilter_link(src, srcpad, dst, dstpad); } +#if defined(LIBAVFILTER_AVFRAME_BASED) + virtual int av_buffersink_get_frame(AVFilterContext *ctx, AVFrame *frame) { return ::av_buffersink_get_frame(ctx, frame); } +#else virtual int av_buffersink_get_buffer_ref(AVFilterContext *buffer_sink, AVFilterBufferRef **bufref, int flags) { return ::av_buffersink_get_buffer_ref(buffer_sink, bufref, flags); } +#endif virtual AVBufferSinkParams *av_buffersink_params_alloc() { return ::av_buffersink_params_alloc(); } +#if !defined(LIBAVFILTER_AVFRAME_BASED) virtual int av_buffersink_poll_frame(AVFilterContext *ctx) { return ::av_buffersink_poll_frame(ctx); } +#endif // DLL faking. virtual bool ResolveExports() { return true; } virtual bool Load() { @@ -182,11 +202,19 @@ class DllAvFilter : public DllDynamic, DllAvFilterInterface #else DEFINE_METHOD3(int, av_vsrc_buffer_add_frame, (AVFilterContext *p1, AVFrame *p2, int p3)) #endif +#if !defined(LIBAVFILTER_AVFRAME_BASED) DEFINE_METHOD1(void, avfilter_unref_buffer, (AVFilterBufferRef *p1)) +#endif DEFINE_METHOD4(int, avfilter_link, (AVFilterContext *p1, unsigned p2, AVFilterContext *p3, unsigned p4)) +#if defined(LIBAVFILTER_AVFRAME_BASED) + DEFINE_FUNC_ALIGNED2(int , __cdecl, av_buffersink_get_frame, AVFilterContext *, AVFrame *); +#else DEFINE_FUNC_ALIGNED3(int , __cdecl, av_buffersink_get_buffer_ref, AVFilterContext *, AVFilterBufferRef **, int); +#endif DEFINE_FUNC_ALIGNED0(AVBufferSinkParams*, __cdecl, av_buffersink_params_alloc); +#if !defined(LIBAVFILTER_AVFRAME_BASED) DEFINE_FUNC_ALIGNED1(int , __cdecl, av_buffersink_poll_frame, AVFilterContext *); +#endif BEGIN_METHOD_RESOLVE() RESOLVE_METHOD_RENAME(avfilter_free, avfilter_free_dont_call) @@ -204,11 +232,19 @@ class DllAvFilter : public DllDynamic, DllAvFilterInterface #else RESOLVE_METHOD(av_buffersrc_add_frame) #endif +#if !defined(LIBAVFILTER_AVFRAME_BASED) RESOLVE_METHOD(avfilter_unref_buffer) +#endif RESOLVE_METHOD(avfilter_link) +#if defined(LIBAVFILTER_AVFRAME_BASED) + RESOLVE_METHOD(av_buffersink_get_frame) +#else RESOLVE_METHOD(av_buffersink_get_buffer_ref) +#endif RESOLVE_METHOD(av_buffersink_params_alloc) +#if !defined(LIBAVFILTER_AVFRAME_BASED) RESOLVE_METHOD(av_buffersink_poll_frame) +#endif END_METHOD_RESOLVE() /* dependencies of libavfilter */ diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp index 5820dfebeb..5a1a47224c 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp @@ -147,7 +147,11 @@ CDVDVideoCodecFFmpeg::CDVDVideoCodecFFmpeg() : CDVDVideoCodec() m_pFilterGraph = NULL; m_pFilterIn = NULL; m_pFilterOut = NULL; +#if defined(LIBAVFILTER_AVFRAME_BASED) + m_pFilterFrame = NULL; +#else m_pBufferRef = NULL; +#endif m_iPictureWidth = 0; m_iPictureHeight = 0; @@ -305,6 +309,11 @@ bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options m_pFrame = m_dllAvCodec.avcodec_alloc_frame(); if (!m_pFrame) return false; +#if defined(LIBAVFILTER_AVFRAME_BASED) + m_pFilterFrame = m_dllAvUtil.av_frame_alloc(); + if (!m_pFilterFrame) return false; +#endif + UpdateName(); return true; } @@ -314,6 +323,10 @@ void CDVDVideoCodecFFmpeg::Dispose() if (m_pFrame) m_dllAvUtil.av_free(m_pFrame); m_pFrame = NULL; +#if defined(LIBAVFILTER_AVFRAME_BASED) + m_dllAvUtil.av_frame_free(&m_pFilterFrame); +#endif + if (m_pCodecContext) { if (m_pCodecContext->codec) m_dllAvCodec.avcodec_close(m_pCodecContext); @@ -553,14 +566,16 @@ void CDVDVideoCodecFFmpeg::Reset() bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture) { - pDvdVideoPicture->iWidth = m_pCodecContext->width; - pDvdVideoPicture->iHeight = m_pCodecContext->height; + pDvdVideoPicture->iWidth = m_pFrame->width; + pDvdVideoPicture->iHeight = m_pFrame->height; +#if !defined(LIBAVFILTER_AVFRAME_BASED) if(m_pBufferRef) { pDvdVideoPicture->iWidth = m_pBufferRef->video->w; pDvdVideoPicture->iHeight = m_pBufferRef->video->h; } +#endif /* crop of 10 pixels if demuxer asked it */ if(m_pCodecContext->coded_width && m_pCodecContext->coded_width < (int)pDvdVideoPicture->iWidth @@ -574,13 +589,15 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture) double aspect_ratio; /* use variable in the frame */ - AVRational pixel_aspect = m_pCodecContext->sample_aspect_ratio; + AVRational pixel_aspect = m_pFrame->sample_aspect_ratio; +#if !defined(LIBAVFILTER_AVFRAME_BASED) if (m_pBufferRef) #if defined(LIBAVFILTER_FROM_FFMPEG) pixel_aspect = m_pBufferRef->video->sample_aspect_ratio; #else pixel_aspect = m_pBufferRef->video->pixel_aspect; #endif +#endif if (pixel_aspect.num == 0) aspect_ratio = 0; @@ -675,10 +692,12 @@ bool CDVDVideoCodecFFmpeg::GetPicture(DVDVideoPicture* pDvdVideoPicture) pDvdVideoPicture->extended_format = 0; PixelFormat pix_fmt; +#if !defined(LIBAVFILTER_AVFRAME_BASED) if(m_pBufferRef) pix_fmt = (PixelFormat)m_pBufferRef->format; else - pix_fmt = m_pCodecContext->pix_fmt; +#endif + pix_fmt = (PixelFormat)m_pFrame->format; pDvdVideoPicture->format = CDVDCodecUtils::EFormatFromPixfmt(pix_fmt); return true; @@ -785,11 +804,13 @@ int CDVDVideoCodecFFmpeg::FilterOpen(const CStdString& filters, bool scale) void CDVDVideoCodecFFmpeg::FilterClose() { +#if !defined(LIBAVFILTER_AVFRAME_BASED) if(m_pBufferRef) { m_dllAvFilter.avfilter_unref_buffer(m_pBufferRef); m_pBufferRef = NULL; } +#endif if (m_pFilterGraph) { @@ -803,7 +824,7 @@ void CDVDVideoCodecFFmpeg::FilterClose() int CDVDVideoCodecFFmpeg::FilterProcess(AVFrame* frame) { - int result, frames; + int result; if (frame) { @@ -830,6 +851,24 @@ int CDVDVideoCodecFFmpeg::FilterProcess(AVFrame* frame) } } +#if defined(LIBAVFILTER_AVFRAME_BASED) + result = m_dllAvFilter.av_buffersink_get_frame(m_pFilterOut, m_pFilterFrame); + + if(result == AVERROR(EAGAIN) || result == AVERROR_EOF) + return VC_BUFFER; + else if(result < 0) + { + CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterProcess - av_buffersink_get_frame"); + return VC_ERROR; + } + + m_dllAvUtil.av_frame_unref(m_pFrame); + m_dllAvUtil.av_frame_move_ref(m_pFrame, m_pFilterFrame); + + return VC_PICTURE; +#else + int frames; + if(m_pBufferRef) { m_dllAvFilter.avfilter_unref_buffer(m_pBufferRef); @@ -870,6 +909,7 @@ int CDVDVideoCodecFFmpeg::FilterProcess(AVFrame* frame) } return VC_BUFFER; +#endif } unsigned CDVDVideoCodecFFmpeg::GetConvergeCount() diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h index 28416e6fb8..c509339a91 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h @@ -99,7 +99,11 @@ protected: AVFilterGraph* m_pFilterGraph; AVFilterContext* m_pFilterIn; AVFilterContext* m_pFilterOut; +#if defined(LIBAVFILTER_AVFRAME_BASED) + AVFrame* m_pFilterFrame; +#else AVFilterBufferRef* m_pBufferRef; +#endif int m_iPictureWidth; int m_iPictureHeight; |