2 * Copyright (C) 2005-2013 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
22 #if (defined HAVE_CONFIG_H) && (!defined TARGET_WINDOWS)
25 #include "DVDVideoCodecFFmpeg.h"
26 #include "DVDDemuxers/DVDDemux.h"
27 #include "DVDStreamInfo.h"
29 #include "DVDCodecs/DVDCodecs.h"
30 #include "DVDCodecs/DVDCodecUtils.h"
31 #include "DVDVideoPPFFmpeg.h"
32 #if defined(TARGET_POSIX) || defined(TARGET_WINDOWS)
33 #include "utils/CPUInfo.h"
35 #include "settings/AdvancedSettings.h"
36 #include "settings/Settings.h"
37 #include "utils/log.h"
38 #include "boost/shared_ptr.hpp"
39 #include "threads/Atomics.h"
42 #define RINT(x) ((x) >= 0 ? ((int)((x) + 0.5)) : ((int)((x) - 0.5)))
48 #include "cores/VideoRenderers/RenderManager.h"
49 #include "cores/VideoRenderers/RenderFormats.h"
60 #ifdef TARGET_DARWIN_OSX
64 using namespace boost;
66 enum PixelFormat CDVDVideoCodecFFmpeg::GetFormat( struct AVCodecContext * avctx
67 , const PixelFormat * fmt )
69 CDVDVideoCodecFFmpeg* ctx = (CDVDVideoCodecFFmpeg*)avctx->opaque;
71 if(!ctx->IsHardwareAllowed())
72 return ctx->m_dllAvCodec.avcodec_default_get_format(avctx, fmt);
74 const PixelFormat * cur = fmt;
75 while(*cur != PIX_FMT_NONE)
78 if(CVDPAU::IsVDPAUFormat(*cur) && CSettings::Get().GetBool("videoplayer.usevdpau"))
80 CLog::Log(LOGNOTICE,"CDVDVideoCodecFFmpeg::GetFormat - Creating VDPAU(%ix%i)", avctx->width, avctx->height);
81 CVDPAU* vdp = new CVDPAU();
82 if(vdp->Open(avctx, *cur))
84 ctx->SetHardware(vdp);
92 if(DXVA::CDecoder::Supports(*cur) && CSettings::Get().GetBool("videoplayer.usedxva2"))
94 DXVA::CDecoder* dec = new DXVA::CDecoder();
95 if(dec->Open(avctx, *cur, ctx->m_uSurfacesCount))
97 ctx->SetHardware(dec);
105 // mpeg4 vaapi decoding is disabled
106 if(*cur == PIX_FMT_VAAPI_VLD && CSettings::Get().GetBool("videoplayer.usevaapi")
107 && (avctx->codec_id != CODEC_ID_MPEG4 || g_advancedSettings.m_videoAllowMpeg4VAAPI))
109 if (ctx->GetHardware() != NULL)
111 ctx->SetHardware(NULL);
114 VAAPI::CDecoder* dec = new VAAPI::CDecoder();
115 if(dec->Open(avctx, *cur, ctx->m_uSurfacesCount))
117 ctx->SetHardware(dec);
125 #ifdef TARGET_DARWIN_OSX
126 if (*cur == AV_PIX_FMT_VDA_VLD && CSettings::Get().GetBool("videoplayer.usevda"))
128 VDA::CDecoder* dec = new VDA::CDecoder();
129 if(dec->Open(avctx, *cur, ctx->m_uSurfacesCount))
131 ctx->SetHardware(dec);
140 return ctx->m_dllAvCodec.avcodec_default_get_format(avctx, fmt);
143 CDVDVideoCodecFFmpeg::CDVDVideoCodecFFmpeg() : CDVDVideoCodec()
145 m_pCodecContext = NULL;
147 m_pFilterGraph = NULL;
153 m_iPictureHeight = 0;
155 m_uSurfacesCount = 0;
164 m_dts = DVD_NOPTS_VALUE;
168 CDVDVideoCodecFFmpeg::~CDVDVideoCodecFFmpeg()
173 bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options)
177 if(!m_dllAvUtil.Load()
178 || !m_dllAvCodec.Load()
179 || !m_dllSwScale.Load()
180 || !m_dllPostProc.Load()
181 || !m_dllAvFilter.Load()
184 m_dllAvCodec.avcodec_register_all();
185 m_dllAvFilter.avfilter_register_all();
187 m_bSoftware = hints.software;
188 m_iOrientation = hints.orientation;
190 for(std::vector<ERenderFormat>::iterator it = options.m_formats.begin(); it != options.m_formats.end(); ++it)
192 m_formats.push_back((PixelFormat)CDVDCodecUtils::PixfmtFromEFormat(*it));
193 if(*it == RENDER_FMT_YUV420P)
194 m_formats.push_back(PIX_FMT_YUVJ420P);
196 m_formats.push_back(PIX_FMT_NONE); /* always add none to get a terminated list in ffmpeg world */
199 m_pCodecContext = NULL;
201 if (hints.codec == CODEC_ID_H264)
203 switch(hints.profile)
205 case FF_PROFILE_H264_HIGH_10:
206 case FF_PROFILE_H264_HIGH_10_INTRA:
207 case FF_PROFILE_H264_HIGH_422:
208 case FF_PROFILE_H264_HIGH_422_INTRA:
209 case FF_PROFILE_H264_HIGH_444_PREDICTIVE:
210 case FF_PROFILE_H264_HIGH_444_INTRA:
211 case FF_PROFILE_H264_CAVLC_444:
212 // this is needed to not open the decoders
214 // this we need to enable multithreading for hi10p via advancedsettings
221 pCodec = m_dllAvCodec.avcodec_find_decoder(hints.codec);
225 CLog::Log(LOGDEBUG,"CDVDVideoCodecFFmpeg::Open() Unable to find codec %d", hints.codec);
229 CLog::Log(LOGNOTICE,"CDVDVideoCodecFFmpeg::Open() Using codec: %s",pCodec->long_name ? pCodec->long_name : pCodec->name);
231 if(m_pCodecContext == NULL)
232 m_pCodecContext = m_dllAvCodec.avcodec_alloc_context3(pCodec);
234 m_pCodecContext->opaque = (void*)this;
235 m_pCodecContext->debug_mv = 0;
236 m_pCodecContext->debug = 0;
237 m_pCodecContext->workaround_bugs = FF_BUG_AUTODETECT;
238 m_pCodecContext->get_format = GetFormat;
239 m_pCodecContext->codec_tag = hints.codec_tag;
240 /* Only allow slice threading, since frame threading is more
241 * sensitive to changes in frame sizes, and it causes crashes
242 * during HW accell - so we unset it in this case.
244 * When we detect Hi10p and user did not disable hi10pmultithreading
245 * via advancedsettings.xml we keep the ffmpeg default thread type.
247 if(m_isHi10p && !g_advancedSettings.m_videoDisableHi10pMultithreading)
249 CLog::Log(LOGDEBUG,"CDVDVideoCodecFFmpeg::Open() Keep default threading for Hi10p: %d",
250 m_pCodecContext->thread_type);
253 m_pCodecContext->thread_type = FF_THREAD_SLICE;
255 #if defined(TARGET_DARWIN_IOS)
256 // ffmpeg with enabled neon will crash and burn if this is enabled
257 m_pCodecContext->flags &= CODEC_FLAG_EMU_EDGE;
259 if (pCodec->id != CODEC_ID_H264 && pCodec->capabilities & CODEC_CAP_DR1
260 && pCodec->id != CODEC_ID_VP8
262 m_pCodecContext->flags |= CODEC_FLAG_EMU_EDGE;
265 // if we don't do this, then some codecs seem to fail.
266 m_pCodecContext->coded_height = hints.height;
267 m_pCodecContext->coded_width = hints.width;
268 m_pCodecContext->bits_per_coded_sample = hints.bitsperpixel;
270 if( hints.extradata && hints.extrasize > 0 )
272 m_pCodecContext->extradata_size = hints.extrasize;
273 m_pCodecContext->extradata = (uint8_t*)m_dllAvUtil.av_mallocz(hints.extrasize + FF_INPUT_BUFFER_PADDING_SIZE);
274 memcpy(m_pCodecContext->extradata, hints.extradata, hints.extrasize);
277 // advanced setting override for skip loop filter (see avcodec.h for valid options)
278 // TODO: allow per video setting?
279 if (g_advancedSettings.m_iSkipLoopFilter != 0)
281 m_pCodecContext->skip_loop_filter = (AVDiscard)g_advancedSettings.m_iSkipLoopFilter;
284 // set any special options
285 for(std::vector<CDVDCodecOption>::iterator it = options.m_keys.begin(); it != options.m_keys.end(); ++it)
287 if (it->m_name == "surfaces")
288 m_uSurfacesCount = std::atoi(it->m_value.c_str());
290 m_dllAvUtil.av_opt_set(m_pCodecContext, it->m_name.c_str(), it->m_value.c_str(), 0);
293 int num_threads = std::min(8 /*MAX_THREADS*/, g_cpuInfo.getCPUCount());
294 if( num_threads > 1 && !hints.software && m_pHardware == NULL // thumbnail extraction fails when run threaded
295 && ( pCodec->id == CODEC_ID_H264
296 || pCodec->id == CODEC_ID_MPEG4 ))
297 m_pCodecContext->thread_count = num_threads;
299 if (m_dllAvCodec.avcodec_open2(m_pCodecContext, pCodec, NULL) < 0)
301 CLog::Log(LOGDEBUG,"CDVDVideoCodecFFmpeg::Open() Unable to open codec");
305 m_pFrame = m_dllAvCodec.avcodec_alloc_frame();
306 if (!m_pFrame) return false;
312 void CDVDVideoCodecFFmpeg::Dispose()
314 if (m_pFrame) m_dllAvUtil.av_free(m_pFrame);
319 if (m_pCodecContext->codec) m_dllAvCodec.avcodec_close(m_pCodecContext);
320 if (m_pCodecContext->extradata)
322 m_dllAvUtil.av_free(m_pCodecContext->extradata);
323 m_pCodecContext->extradata = NULL;
324 m_pCodecContext->extradata_size = 0;
326 m_dllAvUtil.av_free(m_pCodecContext);
327 m_pCodecContext = NULL;
329 SAFE_RELEASE(m_pHardware);
333 m_dllAvCodec.Unload();
334 m_dllAvUtil.Unload();
335 m_dllAvFilter.Unload();
336 m_dllPostProc.Unload();
339 void CDVDVideoCodecFFmpeg::SetDropState(bool bDrop)
341 if( m_pCodecContext )
343 // i don't know exactly how high this should be set
344 // couldn't find any good docs on it. think it varies
345 // from codec to codec on what it does
347 // 2 seem to be to high.. it causes video to be ruined on following images
350 m_pCodecContext->skip_frame = AVDISCARD_NONREF;
351 m_pCodecContext->skip_idct = AVDISCARD_NONREF;
352 m_pCodecContext->skip_loop_filter = AVDISCARD_NONREF;
356 m_pCodecContext->skip_frame = AVDISCARD_DEFAULT;
357 m_pCodecContext->skip_idct = AVDISCARD_DEFAULT;
358 m_pCodecContext->skip_loop_filter = AVDISCARD_DEFAULT;
363 unsigned int CDVDVideoCodecFFmpeg::SetFilters(unsigned int flags)
365 m_filters_next.Empty();
370 if(flags & FILTER_ROTATE)
372 switch(m_iOrientation)
375 m_filters_next += "transpose=1";
378 m_filters_next += "vflip,hflip";
381 m_filters_next += "transpose=2";
388 if(flags & FILTER_DEINTERLACE_YADIF)
390 if(flags & FILTER_DEINTERLACE_HALFED)
391 m_filters_next = "yadif=0:-1";
393 m_filters_next = "yadif=1:-1";
395 if(flags & FILTER_DEINTERLACE_FLAGGED)
396 m_filters_next += ":1";
398 flags &= ~FILTER_DEINTERLACE_ANY | FILTER_DEINTERLACE_YADIF;
410 static int64_t pts_dtoi(double pts)
417 static double pts_itod(int64_t pts)
424 int CDVDVideoCodecFFmpeg::Decode(uint8_t* pData, int iSize, double dts, double pts)
426 int iGotPicture = 0, len = 0;
428 if (!m_pCodecContext)
434 shared_ptr<CSingleLock> lock;
437 CCriticalSection* section = m_pHardware->Section();
439 lock = shared_ptr<CSingleLock>(new CSingleLock(*section));
443 result = m_pHardware->Check(m_pCodecContext);
445 result = m_pHardware->Decode(m_pCodecContext, NULL);
455 result = FilterProcess(NULL);
461 m_pCodecContext->reordered_opaque = pts_dtoi(pts);
464 m_dllAvCodec.av_init_packet(&avpkt);
467 /* We lie, but this flag is only used by pngdec.c.
468 * Setting it correctly would allow CorePNG decoding. */
469 avpkt.flags = AV_PKT_FLAG_KEY;
470 len = m_dllAvCodec.avcodec_decode_video2(m_pCodecContext, m_pFrame, &iGotPicture, &avpkt);
472 if(m_iLastKeyframe < m_pCodecContext->has_b_frames + 2)
473 m_iLastKeyframe = m_pCodecContext->has_b_frames + 2;
477 CLog::Log(LOGERROR, "%s - avcodec_decode_video returned failure", __FUNCTION__);
484 if(m_pFrame->key_frame)
487 m_iLastKeyframe = m_pCodecContext->has_b_frames + 2;
490 /* put a limit on convergence count to avoid huge mem usage on streams without keyframes */
491 if(m_iLastKeyframe > 300)
492 m_iLastKeyframe = 300;
494 /* h264 doesn't always have keyframes + won't output before first keyframe anyway */
495 if(m_pCodecContext->codec_id == CODEC_ID_H264
496 || m_pCodecContext->codec_id == CODEC_ID_SVQ3)
499 if(m_pHardware == NULL)
501 bool need_scale = std::find( m_formats.begin()
503 , m_pCodecContext->pix_fmt) == m_formats.end();
505 bool need_reopen = false;
506 if(!m_filters.Equals(m_filters_next))
511 if(m_pFilterIn->outputs[0]->format != m_pCodecContext->pix_fmt
512 || m_pFilterIn->outputs[0]->w != m_pCodecContext->width
513 || m_pFilterIn->outputs[0]->h != m_pCodecContext->height)
517 // try to setup new filters
518 if (need_reopen || (need_scale && m_pFilterGraph == NULL))
520 m_filters = m_filters_next;
522 if(FilterOpen(m_filters, need_scale) < 0)
529 result = m_pHardware->Decode(m_pCodecContext, m_pFrame);
530 else if(m_pFilterGraph)
531 result = FilterProcess(m_pFrame);
533 result = VC_PICTURE | VC_BUFFER;
535 if(result & VC_FLUSHED)
541 void CDVDVideoCodecFFmpeg::Reset()
544 m_iLastKeyframe = m_pCodecContext->has_b_frames;
545 m_dllAvCodec.avcodec_flush_buffers(m_pCodecContext);
548 m_pHardware->Reset();
554 bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture)
556 pDvdVideoPicture->iWidth = m_pCodecContext->width;
557 pDvdVideoPicture->iHeight = m_pCodecContext->height;
561 pDvdVideoPicture->iWidth = m_pBufferRef->video->w;
562 pDvdVideoPicture->iHeight = m_pBufferRef->video->h;
565 /* crop of 10 pixels if demuxer asked it */
566 if(m_pCodecContext->coded_width && m_pCodecContext->coded_width < (int)pDvdVideoPicture->iWidth
567 && m_pCodecContext->coded_width > (int)pDvdVideoPicture->iWidth - 10)
568 pDvdVideoPicture->iWidth = m_pCodecContext->coded_width;
570 if(m_pCodecContext->coded_height && m_pCodecContext->coded_height < (int)pDvdVideoPicture->iHeight
571 && m_pCodecContext->coded_height > (int)pDvdVideoPicture->iHeight - 10)
572 pDvdVideoPicture->iHeight = m_pCodecContext->coded_height;
576 /* use variable in the frame */
577 AVRational pixel_aspect = m_pCodecContext->sample_aspect_ratio;
579 pixel_aspect = m_pBufferRef->video->sample_aspect_ratio;
581 if (pixel_aspect.num == 0)
584 aspect_ratio = av_q2d(pixel_aspect) * pDvdVideoPicture->iWidth / pDvdVideoPicture->iHeight;
586 if (aspect_ratio <= 0.0)
587 aspect_ratio = (float)pDvdVideoPicture->iWidth / (float)pDvdVideoPicture->iHeight;
589 /* XXX: we suppose the screen has a 1.0 pixel ratio */ // CDVDVideo will compensate it.
590 pDvdVideoPicture->iDisplayHeight = pDvdVideoPicture->iHeight;
591 pDvdVideoPicture->iDisplayWidth = ((int)RINT(pDvdVideoPicture->iHeight * aspect_ratio)) & -3;
592 if (pDvdVideoPicture->iDisplayWidth > pDvdVideoPicture->iWidth)
594 pDvdVideoPicture->iDisplayWidth = pDvdVideoPicture->iWidth;
595 pDvdVideoPicture->iDisplayHeight = ((int)RINT(pDvdVideoPicture->iWidth / aspect_ratio)) & -3;
599 pDvdVideoPicture->pts = DVD_NOPTS_VALUE;
604 pDvdVideoPicture->iRepeatPicture = 0.5 * m_pFrame->repeat_pict;
605 pDvdVideoPicture->iFlags = DVP_FLAG_ALLOCATED;
606 pDvdVideoPicture->iFlags |= m_pFrame->interlaced_frame ? DVP_FLAG_INTERLACED : 0;
607 pDvdVideoPicture->iFlags |= m_pFrame->top_field_first ? DVP_FLAG_TOP_FIELD_FIRST: 0;
609 pDvdVideoPicture->chroma_position = m_pCodecContext->chroma_sample_location;
610 pDvdVideoPicture->color_primaries = m_pCodecContext->color_primaries;
611 pDvdVideoPicture->color_transfer = m_pCodecContext->color_trc;
612 if(m_pCodecContext->color_range == AVCOL_RANGE_JPEG
613 || m_pCodecContext->pix_fmt == PIX_FMT_YUVJ420P)
614 pDvdVideoPicture->color_range = 1;
616 pDvdVideoPicture->color_range = 0;
618 pDvdVideoPicture->qscale_table = m_pFrame->qscale_table;
619 pDvdVideoPicture->qscale_stride = m_pFrame->qstride;
621 switch (m_pFrame->qscale_type) {
622 case FF_QSCALE_TYPE_MPEG1:
623 pDvdVideoPicture->qscale_type = DVP_QSCALE_MPEG1;
625 case FF_QSCALE_TYPE_MPEG2:
626 pDvdVideoPicture->qscale_type = DVP_QSCALE_MPEG2;
628 case FF_QSCALE_TYPE_H264:
629 pDvdVideoPicture->qscale_type = DVP_QSCALE_H264;
632 pDvdVideoPicture->qscale_type = DVP_QSCALE_UNKNOWN;
635 pDvdVideoPicture->dts = m_dts;
636 m_dts = DVD_NOPTS_VALUE;
637 if (m_pFrame->reordered_opaque)
638 pDvdVideoPicture->pts = pts_itod(m_pFrame->reordered_opaque);
640 pDvdVideoPicture->pts = DVD_NOPTS_VALUE;
643 pDvdVideoPicture->iFlags |= DVP_FLAG_DROPPED;
648 bool CDVDVideoCodecFFmpeg::GetPicture(DVDVideoPicture* pDvdVideoPicture)
651 return m_pHardware->GetPicture(m_pCodecContext, m_pFrame, pDvdVideoPicture);
653 if(!GetPictureCommon(pDvdVideoPicture))
657 for (int i = 0; i < 4; i++)
658 pDvdVideoPicture->data[i] = m_pFrame->data[i];
659 for (int i = 0; i < 4; i++)
660 pDvdVideoPicture->iLineSize[i] = m_pFrame->linesize[i];
663 pDvdVideoPicture->iFlags |= pDvdVideoPicture->data[0] ? 0 : DVP_FLAG_DROPPED;
664 pDvdVideoPicture->extended_format = 0;
668 pix_fmt = (PixelFormat)m_pBufferRef->format;
670 pix_fmt = m_pCodecContext->pix_fmt;
672 pDvdVideoPicture->format = CDVDCodecUtils::EFormatFromPixfmt(pix_fmt);
676 int CDVDVideoCodecFFmpeg::FilterOpen(const CStdString& filters, bool scale)
679 AVBufferSinkParams *buffersink_params;
684 if (filters.IsEmpty() && !scale)
689 CLog::Log(LOGWARNING, "CDVDVideoCodecFFmpeg::FilterOpen - skipped opening filters on hardware decode");
693 if (!(m_pFilterGraph = m_dllAvFilter.avfilter_graph_alloc()))
695 CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterOpen - unable to alloc filter graph");
699 AVFilter* srcFilter = m_dllAvFilter.avfilter_get_by_name("buffer");
700 AVFilter* outFilter = m_dllAvFilter.avfilter_get_by_name("buffersink"); // should be last filter in the graph for now
704 args.Format("%d:%d:%d:%d:%d:%d:%d",
705 m_pCodecContext->width,
706 m_pCodecContext->height,
707 m_pCodecContext->pix_fmt,
708 m_pCodecContext->time_base.num,
709 m_pCodecContext->time_base.den,
710 m_pCodecContext->sample_aspect_ratio.num,
711 m_pCodecContext->sample_aspect_ratio.den);
713 if ((result = m_dllAvFilter.avfilter_graph_create_filter(&m_pFilterIn, srcFilter, "src", args, NULL, m_pFilterGraph)) < 0)
715 CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterOpen - avfilter_graph_create_filter: src");
719 buffersink_params = m_dllAvFilter.av_buffersink_params_alloc();
720 buffersink_params->pixel_fmts = &m_formats[0];
721 #ifdef FF_API_OLD_VSINK_API
722 if ((result = m_dllAvFilter.avfilter_graph_create_filter(&m_pFilterOut, outFilter, "out", NULL, (void*)buffersink_params->pixel_fmts, m_pFilterGraph)) < 0)
724 if ((result = m_dllAvFilter.avfilter_graph_create_filter(&m_pFilterOut, outFilter, "out", NULL, buffersink_params, m_pFilterGraph)) < 0)
727 m_dllAvUtil.av_freep(&buffersink_params);
728 CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterOpen - avfilter_graph_create_filter: out");
731 m_dllAvUtil.av_freep(&buffersink_params);
733 if (!filters.empty())
735 AVFilterInOut* outputs = m_dllAvFilter.avfilter_inout_alloc();
736 AVFilterInOut* inputs = m_dllAvFilter.avfilter_inout_alloc();
738 outputs->name = m_dllAvUtil.av_strdup("in");
739 outputs->filter_ctx = m_pFilterIn;
740 outputs->pad_idx = 0;
741 outputs->next = NULL;
743 inputs->name = m_dllAvUtil.av_strdup("out");
744 inputs->filter_ctx = m_pFilterOut;
748 if ((result = m_dllAvFilter.avfilter_graph_parse(m_pFilterGraph, (const char*)m_filters.c_str(), &inputs, &outputs, NULL)) < 0)
750 CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterOpen - avfilter_graph_parse");
754 m_dllAvFilter.avfilter_inout_free(&outputs);
755 m_dllAvFilter.avfilter_inout_free(&inputs);
759 if ((result = m_dllAvFilter.avfilter_link(m_pFilterIn, 0, m_pFilterOut, 0)) < 0)
761 CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterOpen - avfilter_link");
766 if ((result = m_dllAvFilter.avfilter_graph_config(m_pFilterGraph, NULL)) < 0)
768 CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterOpen - avfilter_graph_config");
775 void CDVDVideoCodecFFmpeg::FilterClose()
779 m_dllAvFilter.avfilter_unref_buffer(m_pBufferRef);
785 m_dllAvFilter.avfilter_graph_free(&m_pFilterGraph);
787 // Disposed by above code
793 int CDVDVideoCodecFFmpeg::FilterProcess(AVFrame* frame)
799 #if (defined(LIBAVFILTER_FROM_LIBAV) && LIBAVFILTER_VERSION_INT >= AV_VERSION_INT(3,5,0)) || \
800 (defined(LIBAVFILTER_FROM_FFMPEG) && LIBAVFILTER_VERSION_INT >= AV_VERSION_INT(3,43,100))
802 // ffmpeg: commit 7e350379f87e7f74420b4813170fe808e2313911 (28 Nov 2012)
803 // not released (post 1.2)
804 // libav: commit 7e350379f87e7f74420b4813170fe808e2313911 (28 Nov 2012)
805 // release v9 (5 January 2013)
806 result = m_dllAvFilter.av_buffersrc_add_frame(m_pFilterIn, frame);
807 #elif defined(LIBAVFILTER_FROM_FFMPEG) && LIBAVFILTER_VERSION_INT >= AV_VERSION_INT(2,72,105)
809 // ffmpeg: commit 7bac2a78c2241df4bcc1665703bb71afd9a3e692 (28 Apr 2012)
810 // release 0.11 (25 May 2012)
811 result = m_dllAvFilter.av_buffersrc_add_frame(m_pFilterIn, frame, 0);
813 result = m_dllAvFilter.av_vsrc_buffer_add_frame(m_pFilterIn, frame, 0);
817 CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterProcess - av_buffersrc_add_frame/av_vsrc_buffer_add_frame");
824 m_dllAvFilter.avfilter_unref_buffer(m_pBufferRef);
828 if ((frames = m_dllAvFilter.av_buffersink_poll_frame(m_pFilterOut)) < 0)
830 CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterProcess - av_buffersink_poll_frame");
837 result = m_dllAvFilter.av_buffersink_get_buffer_ref(m_pFilterOut, &m_pBufferRef, 0);
838 if(!m_pBufferRef || result < 0)
840 CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterProcess - cur_buf");
845 m_pFrame->reordered_opaque = 0;
847 m_pFrame->repeat_pict = -(frames - 1);
849 m_pFrame->interlaced_frame = m_pBufferRef->video->interlaced;
850 m_pFrame->top_field_first = m_pBufferRef->video->top_field_first;
852 memcpy(m_pFrame->linesize, m_pBufferRef->linesize, 4*sizeof(int));
853 memcpy(m_pFrame->data , m_pBufferRef->data , 4*sizeof(uint8_t*));
858 return VC_PICTURE | VC_BUFFER;
864 unsigned CDVDVideoCodecFFmpeg::GetConvergeCount()
867 return m_iLastKeyframe;
872 unsigned CDVDVideoCodecFFmpeg::GetAllowedReferences()
875 return m_pHardware->GetAllowedReferences();