Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

System Libav 0.8 #629

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
74 changes: 73 additions & 1 deletion configure.in
Expand Up @@ -1188,6 +1188,9 @@ if test "$use_external_ffmpeg" = "yes"; then
# libavcore is optional
PKG_CHECK_EXISTS([libavcore], FFMPEG_LIBNAMES="$FFMPEG_LIBNAMES libavcore")

# libswresample doesn't exist in libav
PKG_CHECK_EXISTS([libswresample], [FFMPEG_LIBNAMES="$FFMPEG_LIBNAMES libswresample"; AC_DEFINE([HAVE_LIBSWRESAMPLE], [1], [Define to 1 if you have the `swresample' library (-lswresample).])])

PKG_CHECK_MODULES([FFMPEG], [$FFMPEG_LIBNAMES],
[INCLUDES="$INCLUDES $FFMPEG_CFLAGS"; LIBS="$LIBS $FFMPEG_LIBS"],
AC_MSG_ERROR($missing_library))
Expand All @@ -1210,6 +1213,7 @@ if test "$use_external_ffmpeg" = "yes"; then

# optional
AC_CHECK_HEADERS([libavcore/avcore.h libavcore/samplefmt.h libavutil/mem.h libavutil/samplefmt.h])
AC_CHECK_HEADERS([libavfilter/buffersink.h libavfilter/avcodec.h])

# old FFmpeg have this in libavcodec/opt.h instead:
AC_CHECK_HEADERS([libavutil/opt.h])
Expand Down Expand Up @@ -1237,14 +1241,35 @@ if test "$use_external_ffmpeg" = "yes"; then
AC_DEFINE([USE_EXTERNAL_FFMPEG], [1], [Whether to use external FFmpeg libraries.])

# Disable vdpau support if external libavcodec doesn't have it
AC_CHECK_LIB([avcodec], [ff_vdpau_vc1_decode_picture],,
AC_RUN_IFELSE(
AC_LANG_PROGRAM([[#include <libavcodec/avcodec.h>]],
[[avcodec_register_all();
AVCodec *codec = avcodec_find_decoder_by_name("vc1_vdpau");
return (codec) ? 0 : 1;]]),,
[if test "x$use_vdpau" = "xyes"; then
AC_MSG_ERROR($ffmpeg_vdpau_not_supported)
else
use_vdpau=no
AC_MSG_RESULT($ffmpeg_vdpau_not_supported)
fi])

# Other headers to include if available.
AC_CHECK_HEADERS([libavutil/mathematics.h],,)

# Check if <libavfilter/vsrc_buffer.h> exists and defines old
# av_vsrc_buffer_add_frame() from SoC. This avoids multiple declarations of
# av_vsrc_buffer_add_frame().
AC_COMPILE_IFELSE(
AC_LANG_SOURCE([[
#include <libavfilter/vsrc_buffer.h>
void foo(void)
{
AVRational a;
av_vsrc_buffer_add_frame(NULL, NULL, 0, a);
}
]]), AC_DEFINE([USE_OLD_AV_VSRC_BUFFER_ADD_FRAME],
[1], [Check if SoC av_vsrc_buffer_add_frame() is defined in libavfilter/vsrc_buffer.h.]),)

# Check for 'PIX_FMT_VDPAU_MPEG4' from libavutil
if test "x$use_vdpau" != "xno"; then
AC_LANG_PUSH([C++])
Expand All @@ -1255,6 +1280,53 @@ if test "$use_external_ffmpeg" = "yes"; then
[Whether AVUtil defines PIX_FMT_VDPAU_MPEG4.])],)
AC_LANG_POP([C++])
fi

# Check if ffmpeg/libav defines certain functions
AC_CHECK_FUNCS(avfilter_inout_alloc avfilter_inout_free)
AC_CHECK_FUNCS(av_get_default_channel_layout)

# Check parameters passed to avfilter_graph_parse()
AC_LANG_PUSH([C++])
AC_COMPILE_IFELSE(
[AC_LANG_SOURCE([#define __STDC_CONSTANT_MACROS
#include <libavfilter/avfiltergraph.h>
int test()
{
AVFilterInOut *inputs = NULL, *outputs = NULL;
return avfilter_graph_parse(NULL, NULL, inputs, outputs, NULL);
}
])],
[AC_DEFINE([AVFILTER_GRAPH_PARSE_AVFILTERINOUT_SINGLE_POINTER], [1],
[Define to 1 if avfilter_graph_parse() accepts (AVFilterInOut*) parameters.])],)
AC_LANG_POP([C++])

# Check if libavfilter supports the "buffersink" filter
AC_LANG_PUSH([C++])
AC_RUN_IFELSE(
[AC_LANG_SOURCE([#define __STDC_CONSTANT_MACROS
extern "C"
{
#include <libavfilter/avfilter.h>
#include <libavfilter/buffersink.h>
}
void compile_test(void)
{
av_buffersink_get_buffer_ref(NULL, NULL, 0);
av_buffersink_poll_frame(NULL);
av_buffersink_params_alloc();
}
int main(int argc, char **argv)
{
(void)argc; (void)argv;
avfilter_register_all();
AVFilter *f = avfilter_get_by_name("buffersink");
return (f) ? 0 : 1;
}
])],
[AC_DEFINE([LIBAVFILTER_SUPPORTS_BUFFERSINK], [1],
[Define to 1 if libavfilter supports the `buffersink' filter.])],)
AC_LANG_POP([C++])

CPPFLAGS="$SAVE_CPPFLAGS"
else
AC_MSG_NOTICE($external_ffmpeg_disabled)
Expand Down
45 changes: 41 additions & 4 deletions lib/DllAvFilter.h
Expand Up @@ -43,12 +43,20 @@ extern "C" {
#if (defined USE_EXTERNAL_FFMPEG)
#if (defined HAVE_LIBAVFILTER_AVFILTER_H)
#include <libavfilter/avfiltergraph.h>
#include <libavfilter/buffersink.h>
#include <libavfilter/avcodec.h>
#if (defined USE_OLD_AV_VSRC_BUFFER_ADD_FRAME)
#include <libavfilter/vsrc_buffer.h>
#else
#include <libavfilter/buffersink.h>
#include <libavfilter/avcodec.h>
#endif
#elif (defined HAVE_FFMPEG_AVFILTER_H)
#include <ffmpeg/avfiltergraph.h>
#include <ffmpeg/buffersink.h>
#include <ffmpeg/avcodec.h>
#if (defined USE_OLD_AV_VSRC_BUFFER_ADD_FRAME)
#include <ffmpeg/vsrc_buffer.h>
#else
#include <ffmpeg/buffersink.h>
#include <ffmpeg/avcodec.h>
#endif
#endif
#else
#include "libavfilter/avfiltergraph.h"
Expand All @@ -75,13 +83,19 @@ class DllAvFilterInterface
virtual int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx)=0;
virtual int avfilter_poll_frame(AVFilterLink *link)=0;
virtual int avfilter_request_frame(AVFilterLink *link)=0;
#if (defined USE_OLD_AV_VSRC_BUFFER_ADD_FRAME)
virtual int av_vsrc_buffer_add_frame(AVFilterContext *buffer_filter, AVFrame *frame, int64_t pts, AVRational pixel_aspect)=0;
#else
virtual int av_vsrc_buffer_add_frame(AVFilterContext *buffer_filter, AVFrame *frame, int flags)=0;
#endif
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;
#ifdef LIBAVFILTER_SUPPORTS_BUFFERSINK
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;
#endif
};

#if (defined USE_EXTERNAL_FFMPEG) || (defined TARGET_DARWIN)
Expand Down Expand Up @@ -116,31 +130,54 @@ class DllAvFilter : public DllDynamic, DllAvFilterInterface
virtual AVFilterInOut *avfilter_inout_alloc()
{
CSingleLock lock(DllAvCodec::m_critSection);
#ifdef HAVE_AVFILTER_INOUT_ALLOC
return ::avfilter_inout_alloc();
#else
return (AVFilterInOut*)::av_mallocz(sizeof(AVFilterInOut));
#endif
}
virtual void avfilter_inout_free(AVFilterInOut **inout)
{
CSingleLock lock(DllAvCodec::m_critSection);
#ifdef HAVE_AVFILTER_INOUT_FREE
::avfilter_inout_free(inout);
#else
while (*inout) {
AVFilterInOut *next = (*inout)->next;
::av_freep(&(*inout)->name);
::av_freep(inout);
*inout = next;
}
#endif
}
virtual int avfilter_graph_parse(AVFilterGraph *graph, const char *filters, AVFilterInOut **inputs, AVFilterInOut **outputs, void *log_ctx)
{
CSingleLock lock(DllAvCodec::m_critSection);
#ifdef AVFILTER_GRAPH_PARSE_AVFILTERINOUT_SINGLE_POINTER
return ::avfilter_graph_parse(graph, filters, *inputs, *outputs, log_ctx);
#else
return ::avfilter_graph_parse(graph, filters, inputs, outputs, log_ctx);
#endif
}
virtual int avfilter_graph_config(AVFilterGraph *graphctx, void *log_ctx)
{
return ::avfilter_graph_config(graphctx, log_ctx);
}
virtual int avfilter_poll_frame(AVFilterLink *link) { return ::avfilter_poll_frame(link); }
virtual int avfilter_request_frame(AVFilterLink *link) { return ::avfilter_request_frame(link); }
#if (defined USE_OLD_AV_VSRC_BUFFER_ADD_FRAME)
virtual int av_vsrc_buffer_add_frame(AVFilterContext *buffer_filter, AVFrame *frame, int64_t pts, AVRational pixel_aspect) { return ::av_vsrc_buffer_add_frame(buffer_filter, frame, pts, pixel_aspect); }
#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
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); }
#ifdef LIBAVFILTER_SUPPORTS_BUFFERSINK
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); }
#endif
// DLL faking.
virtual bool ResolveExports() { return true; }
virtual bool Load() {
Expand Down
23 changes: 22 additions & 1 deletion lib/DllAvUtil.h
Expand Up @@ -59,6 +59,10 @@ extern "C" {
#else
#include <ffmpeg/mem.h>
#endif
/* For AVRounding */
#if (defined HAVE_LIBAVUTIL_MATHEMATICS_H)
#include <libavutil/mathematics.h>
#endif
#else
#include "libavutil/avutil.h"
#include "libavutil/crc.h"
Expand Down Expand Up @@ -138,7 +142,24 @@ class DllAvUtilBase : public DllDynamic, DllAvUtilInterface
virtual int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags) { return ::av_dict_set(pm, key, value, flags); }
virtual int av_samples_get_buffer_size (int *linesize, int nb_channels, int nb_samples, enum AVSampleFormat sample_fmt, int align)
{ return ::av_samples_get_buffer_size(linesize, nb_channels, nb_samples, sample_fmt, align); }
virtual int64_t av_get_default_channel_layout(int nb_channels) { return ::av_get_default_channel_layout(nb_channels); }
virtual int64_t av_get_default_channel_layout(int nb_channels)
{
#ifdef HAVE_AV_GET_DEFAULT_CHANNEL_LAYOUT
return ::av_get_default_channel_layout(nb_channels);
#else
switch(nb_channels) {
case 1: return AV_CH_LAYOUT_MONO;
case 2: return AV_CH_LAYOUT_STEREO;
case 3: return AV_CH_LAYOUT_SURROUND;
case 4: return AV_CH_LAYOUT_QUAD;
case 5: return AV_CH_LAYOUT_5POINT0;
case 6: return AV_CH_LAYOUT_5POINT1;
case 7: return AV_CH_LAYOUT_6POINT1;
case 8: return AV_CH_LAYOUT_7POINT1;
default: return 0;
}
#endif
}

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.


// DLL faking.
virtual bool ResolveExports() { return true; }
Expand Down
8 changes: 7 additions & 1 deletion lib/DllSwResample.h
Expand Up @@ -36,7 +36,9 @@ extern "C" {
#pragma warning(disable:4244)
#endif
#if (defined USE_EXTERNAL_FFMPEG)
#include <libswresample/swresample.h>
#ifdef HAVE_LIBSWRESAMPLE
#include <libswresample/swresample.h>
#endif
#else
#include "libswresample/swresample.h"
#endif
Expand All @@ -54,7 +56,11 @@ class DllSwResample : public DllDynamic
// DLL faking.
virtual bool ResolveExports() { return true; }
virtual bool Load() {
#ifdef HAVE_LIBSWRESAMPLE
CLog::Log(LOGDEBUG, "DllAvFormat: Using libswresample system library");
#else
CLog::Log(LOGDEBUG, "DllAvFormat: libswresample unavailable");
#endif
return true;
}
virtual void Unload() {}
Expand Down
43 changes: 37 additions & 6 deletions xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp
Expand Up @@ -551,7 +551,11 @@ bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture)
/* use variable in the frame */
AVRational pixel_aspect = m_pCodecContext->sample_aspect_ratio;
if (m_pBufferRef)
#ifdef HAVE_AVFILTERBUFFERREFVIDEOPROPS_SAMPLE_ASPECT_RATIO
pixel_aspect = m_pBufferRef->video->sample_aspect_ratio;
#else
pixel_aspect = m_pBufferRef->video->pixel_aspect;
#endif

if (pixel_aspect.num == 0)
aspect_ratio = 0;
Expand Down Expand Up @@ -657,7 +661,6 @@ bool CDVDVideoCodecFFmpeg::GetPicture(DVDVideoPicture* pDvdVideoPicture)
int CDVDVideoCodecFFmpeg::FilterOpen(const CStdString& filters, bool scale)
{
int result;
AVBufferSinkParams *buffersink_params;

if (m_pFilterGraph)
FilterClose();
Expand All @@ -678,7 +681,13 @@ int CDVDVideoCodecFFmpeg::FilterOpen(const CStdString& filters, bool scale)
}

AVFilter* srcFilter = m_dllAvFilter.avfilter_get_by_name("buffer");
AVFilter* outFilter = m_dllAvFilter.avfilter_get_by_name("buffersink"); // should be last filter in the graph for now

// should be last filter in the graph for now
#ifdef LIBAVFILTER_SUPPORTS_BUFFERSINK
AVFilter* outFilter = m_dllAvFilter.avfilter_get_by_name("buffersink");
#else
AVFilter* outFilter = m_dllAvFilter.avfilter_get_by_name("nullsink");
#endif

CStdString args;

Expand All @@ -697,7 +706,8 @@ int CDVDVideoCodecFFmpeg::FilterOpen(const CStdString& filters, bool scale)
return result;
}

buffersink_params = m_dllAvFilter.av_buffersink_params_alloc();
#ifdef LIBAVFILTER_SUPPORTS_BUFFERSINK
AVBufferSinkParams *buffersink_params = m_dllAvFilter.av_buffersink_params_alloc();
buffersink_params->pixel_fmts = &m_formats[0];
#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)
Expand All @@ -710,6 +720,7 @@ int CDVDVideoCodecFFmpeg::FilterOpen(const CStdString& filters, bool scale)
return result;
}
m_dllAvUtil.av_freep(&buffersink_params);
#endif

if (!filters.empty())
{
Expand Down Expand Up @@ -777,7 +788,11 @@ int CDVDVideoCodecFFmpeg::FilterProcess(AVFrame* frame)

if (frame)
{
#if (defined USE_OLD_AV_VSRC_BUFFER_ADD_FRAME)
result = m_dllAvFilter.av_vsrc_buffer_add_frame(m_pFilterIn, frame, frame->pts, m_pCodecContext->sample_aspect_ratio);
#else
result = m_dllAvFilter.av_vsrc_buffer_add_frame(m_pFilterIn, frame, 0);
#endif
if (result < 0)
{
CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterProcess - av_vsrc_buffer_add_frame");
Expand All @@ -791,16 +806,32 @@ int CDVDVideoCodecFFmpeg::FilterProcess(AVFrame* frame)
m_pBufferRef = NULL;
}

if ((frames = m_dllAvFilter.av_buffersink_poll_frame(m_pFilterOut)) < 0)
#ifdef LIBAVFILTER_SUPPORTS_BUFFERSINK
frames = m_dllAvFilter.av_buffersink_poll_frame(m_pFilterOut);
#else
AVFilterLink *link = m_pFilterOut->inputs[0];
frames = m_dllAvFilter.avfilter_poll_frame(link);
#endif
if (frames < 0)
{
CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterProcess - avfilter_poll_frame");
CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterProcess - poll_frame");
return VC_ERROR;
}

if (frames > 0)
{

#ifdef LIBAVFILTER_SUPPORTS_BUFFERSINK
result = m_dllAvFilter.av_buffersink_get_buffer_ref(m_pFilterOut, &m_pBufferRef, 0);
#else
if ((result = m_dllAvFilter.avfilter_request_frame(link)) < 0)
{
CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterProcess - avfilter_request_frame");
return VC_ERROR;
}
m_pBufferRef = link->cur_buf;
link->cur_buf = NULL;
#endif

if(!m_pBufferRef)

This comment was marked as spam.

This comment was marked as spam.

{
CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterProcess - cur_buf");
Expand Down