void-packages/srcpkgs/xbmc/patches/200_all_avfilter_buffersink...

297 lines
13 KiB
Diff

commit 1fccb604ac8c4e45ebce6c2743d59140b4a117e0
Author: elupus <elupus@xbmc.org>
Date: Thu Jan 19 20:54:43 2012 +0100
changed: replace old libavfilter integration with null output filter with buffersink
diff --git a/lib/DllAvFilter.h b/lib/DllAvFilter.h
index ea012e8..cf91ee9 100644
--- a/lib/DllAvFilter.h
+++ b/lib/DllAvFilter.h
@@ -43,11 +43,14 @@ extern "C" {
#if (defined USE_EXTERNAL_FFMPEG)
#if (defined HAVE_LIBAVFILTER_AVFILTER_H)
#include <libavfilter/avfiltergraph.h>
+ #include <libavfilter/buffersink.h>
#elif (defined HAVE_FFMPEG_AVFILTER_H)
#include <ffmpeg/avfiltergraph.h>
+ #include <ffmpeg/buffersink.h>
#endif
#else
#include "libavfilter/avfiltergraph.h"
+ #include "libavfilter/buffersink.h"
#endif
}
@@ -73,6 +76,9 @@ public:
virtual AVFilterBufferRef *avfilter_get_video_buffer(AVFilterLink *link, int perms, int w, int h)=0;
virtual void avfilter_unref_buffer(AVFilterBufferRef *ref)=0;
virtual int avfilter_link(AVFilterContext *src, unsigned srcpad, AVFilterContext *dst, unsigned dstpad)=0;
+ virtual int av_buffersink_get_buffer_ref(AVFilterContext *buffer_sink, AVFilterBufferRef **bufref, int flags)=0;
+ virtual AVBufferSinkParams *av_buffersink_params_alloc()=0;
+ virtual int av_buffersink_poll_frame(AVFilterContext *ctx)=0;
};
#if (defined USE_EXTERNAL_FFMPEG)
@@ -129,6 +135,9 @@ public:
virtual AVFilterBufferRef *avfilter_get_video_buffer(AVFilterLink *link, int perms, int w, int h) { return ::avfilter_get_video_buffer(link, perms, w, h); }
virtual void avfilter_unref_buffer(AVFilterBufferRef *ref) { ::avfilter_unref_buffer(ref); }
virtual int avfilter_link(AVFilterContext *src, unsigned srcpad, AVFilterContext *dst, unsigned dstpad) { return ::avfilter_link(src, srcpad, dst, dstpad); }
+ virtual int av_buffersink_get_buffer_ref(AVFilterContext *buffer_sink, AVFilterBufferRef **bufref, int flags) { return ::av_buffersink_get_buffer_ref(buffer_sink, bufref, flags); }
+ virtual AVBufferSinkParams *av_buffersink_params_alloc() { return ::av_buffersink_params_alloc(); }
+ virtual int av_buffersink_poll_frame(AVFilterContext *ctx) { return av_buffersink_poll_frame(ctx); }
// DLL faking.
virtual bool ResolveExports() { return true; }
virtual bool Load() {
@@ -153,14 +162,17 @@ class DllAvFilter : public DllDynamic, DllAvFilterInterface
DEFINE_METHOD0(AVFilterGraph*, avfilter_graph_alloc)
DEFINE_METHOD0(AVFilterInOut*, avfilter_inout_alloc_dont_call)
DEFINE_METHOD1(void, avfilter_inout_free_dont_call, (AVFilterInOut **p1))
- DEFINE_METHOD5(int, avfilter_graph_parse_dont_call, (AVFilterGraph *p1, const char *p2, AVFilterInOut **p3, AVFilterInOut **p4, void *p5))
- DEFINE_METHOD2(int, avfilter_graph_config_dont_call, (AVFilterGraph *p1, void *p2))
+ DEFINE_FUNC_ALIGNED5(int, __cdecl, avfilter_graph_parse_dont_call, AVFilterGraph *, const char *, AVFilterInOut **, AVFilterInOut **, void *)
+ DEFINE_FUNC_ALIGNED2(int, __cdecl, avfilter_graph_config_dont_call, AVFilterGraph *, void *)
DEFINE_FUNC_ALIGNED1(int, __cdecl, avfilter_poll_frame, AVFilterLink *)
DEFINE_FUNC_ALIGNED1(int, __cdecl, avfilter_request_frame, AVFilterLink*)
DEFINE_METHOD3(int, av_vsrc_buffer_add_frame, (AVFilterContext *p1, AVFrame *p2, int p3))
DEFINE_METHOD4(AVFilterBufferRef*, avfilter_get_video_buffer, (AVFilterLink *p1, int p2, int p3, int p4))
DEFINE_METHOD1(void, avfilter_unref_buffer, (AVFilterBufferRef *p1))
DEFINE_METHOD4(int, avfilter_link, (AVFilterContext *p1, unsigned p2, AVFilterContext *p3, unsigned p4))
+ DEFINE_FUNC_ALIGNED3(int , __cdecl, av_buffersink_get_buffer_ref, AVFilterContext *, AVFilterBufferRef **, int);
+ DEFINE_FUNC_ALIGNED0(AVBufferSinkParams*, __cdecl, av_buffersink_params_alloc);
+ DEFINE_FUNC_ALIGNED1(int , __cdecl, av_buffersink_poll_frame, AVFilterContext *);
BEGIN_METHOD_RESOLVE()
RESOLVE_METHOD_RENAME(avfilter_open, avfilter_open_dont_call)
@@ -180,6 +192,9 @@ class DllAvFilter : public DllDynamic, DllAvFilterInterface
RESOLVE_METHOD(avfilter_get_video_buffer)
RESOLVE_METHOD(avfilter_unref_buffer)
RESOLVE_METHOD(avfilter_link)
+ RESOLVE_METHOD(av_buffersink_get_buffer_ref)
+ RESOLVE_METHOD(av_buffersink_params_alloc)
+ RESOLVE_METHOD(av_buffersink_poll_frame)
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 74f2431..39f653e 100644
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
@@ -128,7 +128,7 @@ CDVDVideoCodecFFmpeg::CDVDVideoCodecFFmpeg() : CDVDVideoCodec()
m_pFilterGraph = NULL;
m_pFilterIn = NULL;
m_pFilterOut = NULL;
- m_pFilterLink = NULL;
+ m_pBufferRef = NULL;
m_iPictureWidth = 0;
m_iPictureHeight = 0;
@@ -578,10 +578,10 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture)
pDvdVideoPicture->iWidth = m_pCodecContext->width;
pDvdVideoPicture->iHeight = m_pCodecContext->height;
- if(m_pFilterLink)
+ if(m_pBufferRef)
{
- pDvdVideoPicture->iWidth = m_pFilterLink->cur_buf->video->w;
- pDvdVideoPicture->iHeight = m_pFilterLink->cur_buf->video->h;
+ pDvdVideoPicture->iWidth = m_pBufferRef->video->w;
+ pDvdVideoPicture->iHeight = m_pBufferRef->video->h;
}
/* crop of 10 pixels if demuxer asked it */
@@ -597,8 +597,8 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture)
/* use variable in the frame */
AVRational pixel_aspect = m_pCodecContext->sample_aspect_ratio;
- if (m_pFilterLink)
- pixel_aspect = m_pFilterLink->cur_buf->video->sample_aspect_ratio;
+ if (m_pBufferRef)
+ pixel_aspect = m_pBufferRef->video->sample_aspect_ratio;
if (pixel_aspect.num == 0)
aspect_ratio = 0;
@@ -627,8 +627,6 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture)
pDvdVideoPicture->iFlags = DVP_FLAG_ALLOCATED;
pDvdVideoPicture->iFlags |= m_pFrame->interlaced_frame ? DVP_FLAG_INTERLACED : 0;
pDvdVideoPicture->iFlags |= m_pFrame->top_field_first ? DVP_FLAG_TOP_FIELD_FIRST: 0;
- if(m_pCodecContext->pix_fmt == PIX_FMT_YUVJ420P)
- pDvdVideoPicture->color_range = 1;
pDvdVideoPicture->chroma_position = m_pCodecContext->chroma_sample_location;
pDvdVideoPicture->color_primaries = m_pCodecContext->color_primaries;
@@ -688,8 +686,27 @@ bool CDVDVideoCodecFFmpeg::GetPicture(DVDVideoPicture* pDvdVideoPicture)
}
pDvdVideoPicture->iFlags |= pDvdVideoPicture->data[0] ? 0 : DVP_FLAG_DROPPED;
- pDvdVideoPicture->format = DVDVideoPicture::FMT_YUV420P;
pDvdVideoPicture->extended_format = 0;
+ pDvdVideoPicture->color_range = 0;
+
+ PixelFormat pix_fmt;
+ if(m_pBufferRef)
+ pix_fmt = (PixelFormat)m_pBufferRef->format;
+ else if(m_pConvertFrame)
+ pix_fmt = PIX_FMT_YUV420P;
+ else
+ pix_fmt = m_pCodecContext->pix_fmt;
+
+ switch(pix_fmt)
+ {
+ case PIX_FMT_YUVJ420P:
+ pDvdVideoPicture->format = DVDVideoPicture::FMT_YUV420P;
+ pDvdVideoPicture->color_range = 1;
+ break;
+ default:
+ pDvdVideoPicture->format = DVDVideoPicture::FMT_YUV420P;
+ break;
+ }
return true;
}
@@ -697,6 +714,7 @@ bool CDVDVideoCodecFFmpeg::GetPicture(DVDVideoPicture* pDvdVideoPicture)
int CDVDVideoCodecFFmpeg::FilterOpen(const CStdString& filters)
{
int result;
+ AVBufferSinkParams *buffersink_params;
if (m_pFilterGraph)
FilterClose();
@@ -710,17 +728,8 @@ int CDVDVideoCodecFFmpeg::FilterOpen(const CStdString& filters)
return -1;
}
- // CrHasher HACK (if an alternative becomes available use it!): In order to display the output
- // produced by a combination of filters we insert "nullsink" as the last filter and we use
- // its input pin as our output pin.
- //
- // input --> .. --> last_filter --> [in] nullsink [null] [in] --> output
- // | |
- // | |
- // +------------------------+
- //
AVFilter* srcFilter = m_dllAvFilter.avfilter_get_by_name("buffer");
- AVFilter* outFilter = m_dllAvFilter.avfilter_get_by_name("nullsink"); // should be last filter in the graph for now
+ AVFilter* outFilter = m_dllAvFilter.avfilter_get_by_name("buffersink"); // should be last filter in the graph for now
CStdString args;
@@ -739,11 +748,20 @@ int CDVDVideoCodecFFmpeg::FilterOpen(const CStdString& filters)
return result;
}
- if ((result = m_dllAvFilter.avfilter_graph_create_filter(&m_pFilterOut, outFilter, "out", NULL, NULL/*nullsink=>NULL*/, m_pFilterGraph)) < 0)
+ enum PixelFormat pix_fmts[] = { PIX_FMT_YUV420P, PIX_FMT_YUVJ420P, PIX_FMT_NONE };
+ buffersink_params = m_dllAvFilter.av_buffersink_params_alloc();
+ buffersink_params->pixel_fmts = pix_fmts;
+#ifdef FF_API_OLD_VSINK_API
+ if ((result = m_dllAvFilter.avfilter_graph_create_filter(&m_pFilterOut, outFilter, "out", NULL, (void*)buffersink_params->pixel_fmts, m_pFilterGraph)) < 0)
+#else
+ if ((result = m_dllAvFilter.avfilter_graph_create_filter(&m_pFilterOut, outFilter, "out", NULL, buffersink_params, m_pFilterGraph)) < 0)
+#endif
{
+ m_dllAvUtil.av_freep(&buffersink_params);
CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterOpen - avfilter_graph_create_filter: out");
return result;
}
+ m_dllAvUtil.av_freep(&buffersink_params);
if (!filters.empty())
{
@@ -789,6 +807,12 @@ int CDVDVideoCodecFFmpeg::FilterOpen(const CStdString& filters)
void CDVDVideoCodecFFmpeg::FilterClose()
{
+ if(m_pBufferRef)
+ {
+ m_dllAvFilter.avfilter_unref_buffer(m_pBufferRef);
+ m_pBufferRef = NULL;
+ }
+
if (m_pFilterGraph)
{
m_dllAvFilter.avfilter_graph_free(&m_pFilterGraph);
@@ -796,7 +820,6 @@ void CDVDVideoCodecFFmpeg::FilterClose()
// Disposed by above code
m_pFilterIn = NULL;
m_pFilterOut = NULL;
- m_pFilterLink = NULL;
}
}
@@ -804,8 +827,6 @@ int CDVDVideoCodecFFmpeg::FilterProcess(AVFrame* frame)
{
int result, frames;
- m_pFilterLink = m_pFilterOut->inputs[0];
-
if (frame)
{
result = m_dllAvFilter.av_vsrc_buffer_add_frame(m_pFilterIn, frame, 0);
@@ -816,7 +837,13 @@ int CDVDVideoCodecFFmpeg::FilterProcess(AVFrame* frame)
}
}
- if ((frames = m_dllAvFilter.avfilter_poll_frame(m_pFilterLink)) < 0)
+ if(m_pBufferRef)
+ {
+ m_dllAvFilter.avfilter_unref_buffer(m_pBufferRef);
+ m_pBufferRef = NULL;
+ }
+
+ if ((frames = m_dllAvFilter.av_buffersink_poll_frame(m_pFilterOut)) < 0)
{
CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterProcess - avfilter_poll_frame");
return VC_ERROR;
@@ -824,19 +851,9 @@ int CDVDVideoCodecFFmpeg::FilterProcess(AVFrame* frame)
if (frames > 0)
{
- if (m_pFilterLink->cur_buf)
- {
- m_dllAvFilter.avfilter_unref_buffer(m_pFilterLink->cur_buf);
- m_pFilterLink->cur_buf = NULL;
- }
-
- if ((result = m_dllAvFilter.avfilter_request_frame(m_pFilterLink)) < 0)
- {
- CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterProcess - avfilter_request_frame");
- return VC_ERROR;
- }
- if (!m_pFilterLink->cur_buf)
+ result = m_dllAvFilter.av_buffersink_get_buffer_ref(m_pFilterOut, &m_pBufferRef, 0);
+ if(!m_pBufferRef)
{
CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterProcess - cur_buf");
return VC_ERROR;
@@ -847,11 +864,11 @@ int CDVDVideoCodecFFmpeg::FilterProcess(AVFrame* frame)
else
m_pFrame->repeat_pict = -(frames - 1);
- m_pFrame->interlaced_frame = m_pFilterLink->cur_buf->video->interlaced;
- m_pFrame->top_field_first = m_pFilterLink->cur_buf->video->top_field_first;
+ m_pFrame->interlaced_frame = m_pBufferRef->video->interlaced;
+ m_pFrame->top_field_first = m_pBufferRef->video->top_field_first;
- memcpy(m_pFrame->linesize, m_pFilterLink->cur_buf->linesize, 4*sizeof(int));
- memcpy(m_pFrame->data , m_pFilterLink->cur_buf->data , 4*sizeof(uint8_t*));
+ memcpy(m_pFrame->linesize, m_pBufferRef->linesize, 4*sizeof(int));
+ memcpy(m_pFrame->data , m_pBufferRef->data , 4*sizeof(uint8_t*));
if(frames > 1)
return VC_PICTURE;
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h
index 53890cb..0853c51 100644
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.h
@@ -88,7 +88,7 @@ protected:
AVFilterGraph* m_pFilterGraph;
AVFilterContext* m_pFilterIn;
AVFilterContext* m_pFilterOut;
- AVFilterLink* m_pFilterLink;
+ AVFilterBufferRef* m_pBufferRef;
int m_iPictureWidth;
int m_iPictureHeight;