aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexis Ballier <aballier@gentoo.org>2013-07-26 15:48:51 -0400
committerAlexis Ballier <aballier@gentoo.org>2013-08-01 16:12:01 -0400
commit156501303b0175a6cf65fb597528e0e50eaf4aeb (patch)
tree5d5629bef6aebbdb3361528bfe2fed9ac5676598
parentea3b8ccf7aa1cdef19890030341dedacdfd718e8 (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.h36
-rw-r--r--xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp50
-rw-r--r--xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h4
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;