[release] version bump to 13.0 beta1
[vuplus_xbmc] / xbmc / cores / dvdplayer / DVDCodecs / Video / DVDVideoCodecFFmpeg.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
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)
8  *  any later version.
9  *
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.
14  *
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/>.
18  *
19  */
20
21 #include "system.h"
22 #if (defined HAVE_CONFIG_H) && (!defined TARGET_WINDOWS)
23   #include "config.h"
24 #endif
25 #include "DVDVideoCodecFFmpeg.h"
26 #include "DVDDemuxers/DVDDemux.h"
27 #include "DVDStreamInfo.h"
28 #include "DVDClock.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"
34 #endif
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"
40
41 #ifndef TARGET_POSIX
42 #define RINT(x) ((x) >= 0 ? ((int)((x) + 0.5)) : ((int)((x) - 0.5)))
43 #else
44 #include <math.h>
45 #define RINT lrint
46 #endif
47
48 #include "cores/VideoRenderers/RenderManager.h"
49 #include "cores/VideoRenderers/RenderFormats.h"
50
51 #ifdef HAVE_LIBVDPAU
52 #include "VDPAU.h"
53 #endif
54 #ifdef HAS_DX
55 #include "DXVA.h"
56 #endif
57 #ifdef HAVE_LIBVA
58 #include "VAAPI.h"
59 #endif
60 #ifdef TARGET_DARWIN_OSX
61 #include "VDA.h"
62 #endif
63 #include "utils/StringUtils.h"
64
65 using namespace boost;
66
67 enum PixelFormat CDVDVideoCodecFFmpeg::GetFormat( struct AVCodecContext * avctx
68                                                 , const PixelFormat * fmt )
69 {
70   CDVDVideoCodecFFmpeg* ctx  = (CDVDVideoCodecFFmpeg*)avctx->opaque;
71
72   if(!ctx->IsHardwareAllowed())
73     return ctx->m_dllAvCodec.avcodec_default_get_format(avctx, fmt);
74
75   const PixelFormat * cur = fmt;
76   while(*cur != PIX_FMT_NONE)
77   {
78 #ifdef HAVE_LIBVDPAU
79     if(VDPAU::CDecoder::IsVDPAUFormat(*cur) && CSettings::Get().GetBool("videoplayer.usevdpau"))
80     {
81       CLog::Log(LOGNOTICE,"CDVDVideoCodecFFmpeg::GetFormat - Creating VDPAU(%ix%i)", avctx->width, avctx->height);
82       VDPAU::CDecoder* vdp = new VDPAU::CDecoder();
83       if(vdp->Open(avctx, *cur, ctx->m_uSurfacesCount))
84       {
85         ctx->SetHardware(vdp);
86         return *cur;
87       }
88       else
89         vdp->Release();
90     }
91 #endif
92 #ifdef HAS_DX
93   if(DXVA::CDecoder::Supports(*cur) && CSettings::Get().GetBool("videoplayer.usedxva2"))
94   {
95     DXVA::CDecoder* dec = new DXVA::CDecoder();
96     if(dec->Open(avctx, *cur, ctx->m_uSurfacesCount))
97     {
98       ctx->SetHardware(dec);
99       return *cur;
100     }
101     else
102       dec->Release();
103   }
104 #endif
105 #ifdef HAVE_LIBVA
106     // mpeg4 vaapi decoding is disabled
107     if(*cur == PIX_FMT_VAAPI_VLD && CSettings::Get().GetBool("videoplayer.usevaapi") 
108     && (avctx->codec_id != AV_CODEC_ID_MPEG4 || g_advancedSettings.m_videoAllowMpeg4VAAPI)) 
109     {
110       VAAPI::CDecoder* dec = new VAAPI::CDecoder();
111       if(dec->Open(avctx, *cur, ctx->m_uSurfacesCount))
112       {
113         ctx->SetHardware(dec);
114         return *cur;
115       }
116       else
117         dec->Release();
118     }
119 #endif
120
121 #ifdef TARGET_DARWIN_OSX
122     if (*cur == AV_PIX_FMT_VDA_VLD && CSettings::Get().GetBool("videoplayer.usevda"))
123     {
124       VDA::CDecoder* dec = new VDA::CDecoder();
125       if(dec->Open(avctx, *cur, ctx->m_uSurfacesCount))
126       {
127         ctx->SetHardware(dec);
128         return *cur;
129       }
130       else
131         dec->Release();
132     }
133 #endif
134     cur++;
135   }
136   return ctx->m_dllAvCodec.avcodec_default_get_format(avctx, fmt);
137 }
138
139 CDVDVideoCodecFFmpeg::CDVDVideoCodecFFmpeg() : CDVDVideoCodec()
140 {
141   m_pCodecContext = NULL;
142   m_pFrame = NULL;
143   m_pFilterGraph  = NULL;
144   m_pFilterIn     = NULL;
145   m_pFilterOut    = NULL;
146 #if defined(LIBAVFILTER_AVFRAME_BASED)
147   m_pFilterFrame  = NULL;
148 #else
149   m_pBufferRef    = NULL;
150 #endif
151
152   m_iPictureWidth = 0;
153   m_iPictureHeight = 0;
154
155   m_uSurfacesCount = 0;
156
157   m_iScreenWidth = 0;
158   m_iScreenHeight = 0;
159   m_iOrientation = 0;
160   m_bSoftware = false;
161   m_isHi10p = false;
162   m_pHardware = NULL;
163   m_iLastKeyframe = 0;
164   m_dts = DVD_NOPTS_VALUE;
165   m_started = false;
166 }
167
168 CDVDVideoCodecFFmpeg::~CDVDVideoCodecFFmpeg()
169 {
170   Dispose();
171 }
172
173 bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options)
174 {
175   AVCodec* pCodec;
176
177   if(!m_dllAvUtil.Load()
178   || !m_dllAvCodec.Load()
179   || !m_dllSwScale.Load()
180   || !m_dllPostProc.Load()
181   || !m_dllAvFilter.Load()
182   ) return false;
183
184   m_dllAvCodec.avcodec_register_all();
185   m_dllAvFilter.avfilter_register_all();
186
187   m_bSoftware     = hints.software;
188   m_iOrientation  = hints.orientation;
189
190   for(std::vector<ERenderFormat>::iterator it = options.m_formats.begin(); it != options.m_formats.end(); ++it)
191   {
192     m_formats.push_back((PixelFormat)CDVDCodecUtils::PixfmtFromEFormat(*it));
193     if(*it == RENDER_FMT_YUV420P)
194       m_formats.push_back(PIX_FMT_YUVJ420P);
195   }
196   m_formats.push_back(PIX_FMT_NONE); /* always add none to get a terminated list in ffmpeg world */
197
198   pCodec = NULL;
199   m_pCodecContext = NULL;
200
201   if (hints.codec == AV_CODEC_ID_H264)
202   {
203     switch(hints.profile)
204     {
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
213       m_bSoftware = true;
214       // this we need to enable multithreading for hi10p via advancedsettings
215       m_isHi10p = true;
216       break;
217     }
218   }
219
220   if(pCodec == NULL)
221     pCodec = m_dllAvCodec.avcodec_find_decoder(hints.codec);
222
223   if(pCodec == NULL)
224   {
225     CLog::Log(LOGDEBUG,"CDVDVideoCodecFFmpeg::Open() Unable to find codec %d", hints.codec);
226     return false;
227   }
228
229   CLog::Log(LOGNOTICE,"CDVDVideoCodecFFmpeg::Open() Using codec: %s",pCodec->long_name ? pCodec->long_name : pCodec->name);
230
231   if(m_pCodecContext == NULL)
232     m_pCodecContext = m_dllAvCodec.avcodec_alloc_context3(pCodec);
233
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.
243    *
244    * When we detect Hi10p and user did not disable hi10pmultithreading
245    * via advancedsettings.xml we keep the ffmpeg default thread type.
246    * */
247   if(m_isHi10p && !g_advancedSettings.m_videoDisableHi10pMultithreading)
248   {
249     CLog::Log(LOGDEBUG,"CDVDVideoCodecFFmpeg::Open() Keep default threading for Hi10p: %d",
250                         m_pCodecContext->thread_type);
251   }
252   else if (CSettings::Get().GetBool("videoplayer.useframemtdec"))
253   {
254     CLog::Log(LOGDEBUG,"CDVDVideoCodecFFmpeg::Open() Keep default threading %d by videoplayer.useframemtdec",
255                         m_pCodecContext->thread_type);
256   }
257   else
258     m_pCodecContext->thread_type = FF_THREAD_SLICE;
259
260 #if defined(TARGET_DARWIN_IOS)
261   // ffmpeg with enabled neon will crash and burn if this is enabled
262   m_pCodecContext->flags &= CODEC_FLAG_EMU_EDGE;
263 #else
264   if (pCodec->id != AV_CODEC_ID_H264 && pCodec->capabilities & CODEC_CAP_DR1
265       && pCodec->id != AV_CODEC_ID_VP8
266      )
267     m_pCodecContext->flags |= CODEC_FLAG_EMU_EDGE;
268 #endif
269
270   // if we don't do this, then some codecs seem to fail.
271   m_pCodecContext->coded_height = hints.height;
272   m_pCodecContext->coded_width = hints.width;
273   m_pCodecContext->bits_per_coded_sample = hints.bitsperpixel;
274
275   if( hints.extradata && hints.extrasize > 0 )
276   {
277     m_pCodecContext->extradata_size = hints.extrasize;
278     m_pCodecContext->extradata = (uint8_t*)m_dllAvUtil.av_mallocz(hints.extrasize + FF_INPUT_BUFFER_PADDING_SIZE);
279     memcpy(m_pCodecContext->extradata, hints.extradata, hints.extrasize);
280   }
281
282   // advanced setting override for skip loop filter (see avcodec.h for valid options)
283   // TODO: allow per video setting?
284   if (g_advancedSettings.m_iSkipLoopFilter != 0)
285   {
286     m_pCodecContext->skip_loop_filter = (AVDiscard)g_advancedSettings.m_iSkipLoopFilter;
287   }
288
289   // set any special options
290   for(std::vector<CDVDCodecOption>::iterator it = options.m_keys.begin(); it != options.m_keys.end(); ++it)
291   {
292     if (it->m_name == "surfaces")
293       m_uSurfacesCount = std::atoi(it->m_value.c_str());
294     else
295       m_dllAvUtil.av_opt_set(m_pCodecContext, it->m_name.c_str(), it->m_value.c_str(), 0);
296   }
297
298   int num_threads = std::min(8 /*MAX_THREADS*/, g_cpuInfo.getCPUCount());
299   if( num_threads > 1 && !hints.software && m_pHardware == NULL // thumbnail extraction fails when run threaded
300   && ( pCodec->id == AV_CODEC_ID_H264
301     || pCodec->id == AV_CODEC_ID_MPEG4 ))
302     m_pCodecContext->thread_count = num_threads;
303
304   if (m_dllAvCodec.avcodec_open2(m_pCodecContext, pCodec, NULL) < 0)
305   {
306     CLog::Log(LOGDEBUG,"CDVDVideoCodecFFmpeg::Open() Unable to open codec");
307     return false;
308   }
309
310   m_pFrame = m_dllAvCodec.avcodec_alloc_frame();
311   if (!m_pFrame) return false;
312
313 #if defined(LIBAVFILTER_AVFRAME_BASED)
314   m_pFilterFrame = m_dllAvUtil.av_frame_alloc();
315   if (!m_pFilterFrame) return false;
316 #endif
317
318   UpdateName();
319   return true;
320 }
321
322 void CDVDVideoCodecFFmpeg::Dispose()
323 {
324   if (m_pFrame) m_dllAvUtil.av_free(m_pFrame);
325   m_pFrame = NULL;
326
327 #if defined(LIBAVFILTER_AVFRAME_BASED)
328   m_dllAvUtil.av_frame_free(&m_pFilterFrame);
329 #endif
330
331   if (m_pCodecContext)
332   {
333     if (m_pCodecContext->codec) m_dllAvCodec.avcodec_close(m_pCodecContext);
334     if (m_pCodecContext->extradata)
335     {
336       m_dllAvUtil.av_free(m_pCodecContext->extradata);
337       m_pCodecContext->extradata = NULL;
338       m_pCodecContext->extradata_size = 0;
339     }
340     m_dllAvUtil.av_free(m_pCodecContext);
341     m_pCodecContext = NULL;
342   }
343   SAFE_RELEASE(m_pHardware);
344
345   FilterClose();
346
347   m_dllAvCodec.Unload();
348   m_dllAvUtil.Unload();
349   m_dllAvFilter.Unload();
350   m_dllPostProc.Unload();
351 }
352
353 void CDVDVideoCodecFFmpeg::SetDropState(bool bDrop)
354 {
355   if( m_pCodecContext )
356   {
357     // i don't know exactly how high this should be set
358     // couldn't find any good docs on it. think it varies
359     // from codec to codec on what it does
360
361     //  2 seem to be to high.. it causes video to be ruined on following images
362     if( bDrop )
363     {
364       m_pCodecContext->skip_frame = AVDISCARD_NONREF;
365       m_pCodecContext->skip_idct = AVDISCARD_NONREF;
366       m_pCodecContext->skip_loop_filter = AVDISCARD_NONREF;
367     }
368     else
369     {
370       m_pCodecContext->skip_frame = AVDISCARD_DEFAULT;
371       m_pCodecContext->skip_idct = AVDISCARD_DEFAULT;
372       m_pCodecContext->skip_loop_filter = AVDISCARD_DEFAULT;
373     }
374   }
375 }
376
377 unsigned int CDVDVideoCodecFFmpeg::SetFilters(unsigned int flags)
378 {
379   m_filters_next.clear();
380
381   if(m_pHardware)
382     return 0;
383
384   if(flags & FILTER_ROTATE)
385   {
386     switch(m_iOrientation)
387     {
388       case 90:
389         m_filters_next += "transpose=1";
390         break;
391       case 180:
392         m_filters_next += "vflip,hflip";
393         break;
394       case 270:  
395         m_filters_next += "transpose=2";
396         break;
397       default:
398         break;
399       }
400   }
401
402   if(flags & FILTER_DEINTERLACE_YADIF)
403   {
404     if(flags & FILTER_DEINTERLACE_HALFED)
405       m_filters_next = "yadif=0:-1";
406     else
407       m_filters_next = "yadif=1:-1";
408
409     if(flags & FILTER_DEINTERLACE_FLAGGED)
410       m_filters_next += ":1";
411
412     flags &= ~FILTER_DEINTERLACE_ANY | FILTER_DEINTERLACE_YADIF;
413   }
414
415   return flags;
416 }
417
418 union pts_union
419 {
420   double  pts_d;
421   int64_t pts_i;
422 };
423
424 static int64_t pts_dtoi(double pts)
425 {
426   pts_union u;
427   u.pts_d = pts;
428   return u.pts_i;
429 }
430
431 static double pts_itod(int64_t pts)
432 {
433   pts_union u;
434   u.pts_i = pts;
435   return u.pts_d;
436 }
437
438 int CDVDVideoCodecFFmpeg::Decode(uint8_t* pData, int iSize, double dts, double pts)
439 {
440   int iGotPicture = 0, len = 0;
441
442   if (!m_pCodecContext)
443     return VC_ERROR;
444
445   if(pData)
446     m_iLastKeyframe++;
447
448   shared_ptr<CSingleLock> lock;
449   if(m_pHardware)
450   {
451     CCriticalSection* section = m_pHardware->Section();
452     if(section)
453       lock = shared_ptr<CSingleLock>(new CSingleLock(*section));
454
455     int result;
456     if(pData)
457       result = m_pHardware->Check(m_pCodecContext);
458     else
459       result = m_pHardware->Decode(m_pCodecContext, NULL);
460
461     if(result)
462       return result;
463   }
464
465   if(m_pFilterGraph)
466   {
467     int result = 0;
468     if(pData == NULL)
469       result = FilterProcess(NULL);
470     if(result)
471       return result;
472   }
473
474   m_dts = dts;
475   m_pCodecContext->reordered_opaque = pts_dtoi(pts);
476
477   AVPacket avpkt;
478   m_dllAvCodec.av_init_packet(&avpkt);
479   avpkt.data = pData;
480   avpkt.size = iSize;
481   /* We lie, but this flag is only used by pngdec.c.
482    * Setting it correctly would allow CorePNG decoding. */
483   avpkt.flags = AV_PKT_FLAG_KEY;
484   len = m_dllAvCodec.avcodec_decode_video2(m_pCodecContext, m_pFrame, &iGotPicture, &avpkt);
485
486   if(m_iLastKeyframe < m_pCodecContext->has_b_frames + 2)
487     m_iLastKeyframe = m_pCodecContext->has_b_frames + 2;
488
489   if (len < 0)
490   {
491     CLog::Log(LOGERROR, "%s - avcodec_decode_video returned failure", __FUNCTION__);
492     return VC_ERROR;
493   }
494
495   if (!iGotPicture)
496     return VC_BUFFER;
497
498   if(m_pFrame->key_frame)
499   {
500     m_started = true;
501     m_iLastKeyframe = m_pCodecContext->has_b_frames + 2;
502   }
503
504   /* put a limit on convergence count to avoid huge mem usage on streams without keyframes */
505   if(m_iLastKeyframe > 300)
506     m_iLastKeyframe = 300;
507
508   /* h264 doesn't always have keyframes + won't output before first keyframe anyway */
509   if(m_pCodecContext->codec_id == AV_CODEC_ID_H264
510   || m_pCodecContext->codec_id == AV_CODEC_ID_SVQ3)
511     m_started = true;
512
513   if(m_pHardware == NULL)
514   {
515     bool need_scale = std::find( m_formats.begin()
516                                , m_formats.end()
517                                , m_pCodecContext->pix_fmt) == m_formats.end();
518
519     bool need_reopen  = false;
520     if(!m_filters.Equals(m_filters_next))
521       need_reopen = true;
522
523     if(m_pFilterIn)
524     {
525       if(m_pFilterIn->outputs[0]->format != m_pCodecContext->pix_fmt
526       || m_pFilterIn->outputs[0]->w      != m_pCodecContext->width
527       || m_pFilterIn->outputs[0]->h      != m_pCodecContext->height)
528         need_reopen = true;
529     }
530
531     // try to setup new filters
532     if (need_reopen || (need_scale && m_pFilterGraph == NULL))
533     {
534       m_filters = m_filters_next;
535
536       if(FilterOpen(m_filters, need_scale) < 0)
537         FilterClose();
538     }
539   }
540
541   int result;
542   if(m_pHardware)
543     result = m_pHardware->Decode(m_pCodecContext, m_pFrame);
544   else if(m_pFilterGraph)
545     result = FilterProcess(m_pFrame);
546   else
547     result = VC_PICTURE | VC_BUFFER;
548
549   if(result & VC_FLUSHED)
550     Reset();
551
552   return result;
553 }
554
555 void CDVDVideoCodecFFmpeg::Reset()
556 {
557   m_started = false;
558   m_iLastKeyframe = m_pCodecContext->has_b_frames;
559   m_dllAvCodec.avcodec_flush_buffers(m_pCodecContext);
560
561   if (m_pHardware)
562     m_pHardware->Reset();
563
564   m_filters = "";
565   FilterClose();
566 }
567
568 bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture)
569 {
570   pDvdVideoPicture->iWidth = m_pFrame->width;
571   pDvdVideoPicture->iHeight = m_pFrame->height;
572
573 #if !defined(LIBAVFILTER_AVFRAME_BASED)
574   if(m_pBufferRef)
575   {
576     pDvdVideoPicture->iWidth  = m_pBufferRef->video->w;
577     pDvdVideoPicture->iHeight = m_pBufferRef->video->h;
578   }
579 #endif
580
581   /* crop of 10 pixels if demuxer asked it */
582   if(m_pCodecContext->coded_width  && m_pCodecContext->coded_width  < (int)pDvdVideoPicture->iWidth
583                                    && m_pCodecContext->coded_width  > (int)pDvdVideoPicture->iWidth  - 10)
584     pDvdVideoPicture->iWidth = m_pCodecContext->coded_width;
585
586   if(m_pCodecContext->coded_height && m_pCodecContext->coded_height < (int)pDvdVideoPicture->iHeight
587                                    && m_pCodecContext->coded_height > (int)pDvdVideoPicture->iHeight - 10)
588     pDvdVideoPicture->iHeight = m_pCodecContext->coded_height;
589
590   double aspect_ratio;
591
592   /* use variable in the frame */
593   AVRational pixel_aspect = m_pFrame->sample_aspect_ratio;
594 #if !defined(LIBAVFILTER_AVFRAME_BASED)
595   if (m_pBufferRef)
596     pixel_aspect = m_pBufferRef->video->sample_aspect_ratio;
597 #endif
598
599   if (pixel_aspect.num == 0)
600     aspect_ratio = 0;
601   else
602     aspect_ratio = av_q2d(pixel_aspect) * pDvdVideoPicture->iWidth / pDvdVideoPicture->iHeight;
603
604   if (aspect_ratio <= 0.0)
605     aspect_ratio = (float)pDvdVideoPicture->iWidth / (float)pDvdVideoPicture->iHeight;
606
607   /* XXX: we suppose the screen has a 1.0 pixel ratio */ // CDVDVideo will compensate it.
608   pDvdVideoPicture->iDisplayHeight = pDvdVideoPicture->iHeight;
609   pDvdVideoPicture->iDisplayWidth  = ((int)RINT(pDvdVideoPicture->iHeight * aspect_ratio)) & -3;
610   if (pDvdVideoPicture->iDisplayWidth > pDvdVideoPicture->iWidth)
611   {
612     pDvdVideoPicture->iDisplayWidth  = pDvdVideoPicture->iWidth;
613     pDvdVideoPicture->iDisplayHeight = ((int)RINT(pDvdVideoPicture->iWidth / aspect_ratio)) & -3;
614   }
615
616
617   pDvdVideoPicture->pts = DVD_NOPTS_VALUE;
618
619   if (!m_pFrame)
620     return false;
621
622   AVDictionaryEntry * entry = m_dllAvUtil.av_dict_get(m_dllAvCodec.av_frame_get_metadata(m_pFrame), "stereo_mode", NULL, 0);
623   if(entry && entry->value)
624   {
625     strncpy(pDvdVideoPicture->stereo_mode, (const char*)entry->value, sizeof(pDvdVideoPicture->stereo_mode));
626     pDvdVideoPicture->stereo_mode[sizeof(pDvdVideoPicture->stereo_mode)-1] = '\0';
627   }
628
629   pDvdVideoPicture->iRepeatPicture = 0.5 * m_pFrame->repeat_pict;
630   pDvdVideoPicture->iFlags = DVP_FLAG_ALLOCATED;
631   pDvdVideoPicture->iFlags |= m_pFrame->interlaced_frame ? DVP_FLAG_INTERLACED : 0;
632   pDvdVideoPicture->iFlags |= m_pFrame->top_field_first ? DVP_FLAG_TOP_FIELD_FIRST: 0;
633
634   pDvdVideoPicture->chroma_position = m_pCodecContext->chroma_sample_location;
635   pDvdVideoPicture->color_primaries = m_pCodecContext->color_primaries;
636   pDvdVideoPicture->color_transfer = m_pCodecContext->color_trc;
637   if(m_pCodecContext->color_range == AVCOL_RANGE_JPEG
638   || m_pCodecContext->pix_fmt     == PIX_FMT_YUVJ420P)
639     pDvdVideoPicture->color_range = 1;
640   else
641     pDvdVideoPicture->color_range = 0;
642
643   pDvdVideoPicture->qscale_table = m_pFrame->qscale_table;
644   pDvdVideoPicture->qscale_stride = m_pFrame->qstride;
645
646   switch (m_pFrame->qscale_type) {
647   case FF_QSCALE_TYPE_MPEG1:
648     pDvdVideoPicture->qscale_type = DVP_QSCALE_MPEG1;
649     break;
650   case FF_QSCALE_TYPE_MPEG2:
651     pDvdVideoPicture->qscale_type = DVP_QSCALE_MPEG2;
652     break;
653   case FF_QSCALE_TYPE_H264:
654     pDvdVideoPicture->qscale_type = DVP_QSCALE_H264;
655     break;
656   default:
657     pDvdVideoPicture->qscale_type = DVP_QSCALE_UNKNOWN;
658   }
659
660   pDvdVideoPicture->dts = m_dts;
661   m_dts = DVD_NOPTS_VALUE;
662   if (m_pFrame->reordered_opaque)
663     pDvdVideoPicture->pts = pts_itod(m_pFrame->reordered_opaque);
664   else
665     pDvdVideoPicture->pts = DVD_NOPTS_VALUE;
666
667   if(!m_started)
668     pDvdVideoPicture->iFlags |= DVP_FLAG_DROPPED;
669
670   return true;
671 }
672
673 bool CDVDVideoCodecFFmpeg::GetPicture(DVDVideoPicture* pDvdVideoPicture)
674 {
675   if(m_pHardware)
676     return m_pHardware->GetPicture(m_pCodecContext, m_pFrame, pDvdVideoPicture);
677
678   if(!GetPictureCommon(pDvdVideoPicture))
679     return false;
680
681   {
682     for (int i = 0; i < 4; i++)
683       pDvdVideoPicture->data[i]      = m_pFrame->data[i];
684     for (int i = 0; i < 4; i++)
685       pDvdVideoPicture->iLineSize[i] = m_pFrame->linesize[i];
686   }
687
688   pDvdVideoPicture->iFlags |= pDvdVideoPicture->data[0] ? 0 : DVP_FLAG_DROPPED;
689   pDvdVideoPicture->extended_format = 0;
690
691   PixelFormat pix_fmt;
692 #if !defined(LIBAVFILTER_AVFRAME_BASED)
693   if(m_pBufferRef)
694     pix_fmt = (PixelFormat)m_pBufferRef->format;
695   else
696 #endif
697     pix_fmt = (PixelFormat)m_pFrame->format;
698
699   pDvdVideoPicture->format = CDVDCodecUtils::EFormatFromPixfmt(pix_fmt);
700   return true;
701 }
702
703 int CDVDVideoCodecFFmpeg::FilterOpen(const CStdString& filters, bool scale)
704 {
705   int result;
706   AVBufferSinkParams *buffersink_params;
707
708   if (m_pFilterGraph)
709     FilterClose();
710
711   if (filters.empty() && !scale)
712     return 0;
713
714   if (m_pHardware)
715   {
716     CLog::Log(LOGWARNING, "CDVDVideoCodecFFmpeg::FilterOpen - skipped opening filters on hardware decode");
717     return 0;
718   }
719
720   if (!(m_pFilterGraph = m_dllAvFilter.avfilter_graph_alloc()))
721   {
722     CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterOpen - unable to alloc filter graph");
723     return -1;
724   }
725
726   AVFilter* srcFilter = m_dllAvFilter.avfilter_get_by_name("buffer");
727   AVFilter* outFilter = m_dllAvFilter.avfilter_get_by_name("buffersink"); // should be last filter in the graph for now
728
729   CStdString args = StringUtils::Format("%d:%d:%d:%d:%d:%d:%d",
730                                         m_pCodecContext->width,
731                                         m_pCodecContext->height,
732                                         m_pCodecContext->pix_fmt,
733                                         m_pCodecContext->time_base.num,
734                                         m_pCodecContext->time_base.den,
735                                         m_pCodecContext->sample_aspect_ratio.num,
736                                         m_pCodecContext->sample_aspect_ratio.den);
737
738   if ((result = m_dllAvFilter.avfilter_graph_create_filter(&m_pFilterIn, srcFilter, "src", args, NULL, m_pFilterGraph)) < 0)
739   {
740     CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterOpen - avfilter_graph_create_filter: src");
741     return result;
742   }
743
744   buffersink_params = m_dllAvFilter.av_buffersink_params_alloc();
745   buffersink_params->pixel_fmts = &m_formats[0];
746 #ifdef FF_API_OLD_VSINK_API
747   if ((result = m_dllAvFilter.avfilter_graph_create_filter(&m_pFilterOut, outFilter, "out", NULL, (void*)buffersink_params->pixel_fmts, m_pFilterGraph)) < 0)
748 #else
749   if ((result = m_dllAvFilter.avfilter_graph_create_filter(&m_pFilterOut, outFilter, "out", NULL, buffersink_params, m_pFilterGraph)) < 0)
750 #endif
751   {
752     m_dllAvUtil.av_freep(&buffersink_params);
753     CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterOpen - avfilter_graph_create_filter: out");
754     return result;
755   }
756   m_dllAvUtil.av_freep(&buffersink_params);
757
758   if (!filters.empty())
759   {
760     AVFilterInOut* outputs = m_dllAvFilter.avfilter_inout_alloc();
761     AVFilterInOut* inputs  = m_dllAvFilter.avfilter_inout_alloc();
762
763     outputs->name    = m_dllAvUtil.av_strdup("in");
764     outputs->filter_ctx = m_pFilterIn;
765     outputs->pad_idx = 0;
766     outputs->next    = NULL;
767
768     inputs->name    = m_dllAvUtil.av_strdup("out");
769     inputs->filter_ctx = m_pFilterOut;
770     inputs->pad_idx = 0;
771     inputs->next    = NULL;
772
773 #if defined(HAVE_AVFILTER_GRAPH_PARSE_PTR)
774     if ((result = m_dllAvFilter.avfilter_graph_parse_ptr(m_pFilterGraph, (const char*)m_filters.c_str(), &inputs, &outputs, NULL)) < 0)
775 #else
776     if ((result = m_dllAvFilter.avfilter_graph_parse(m_pFilterGraph, (const char*)m_filters.c_str(), &inputs, &outputs, NULL)) < 0)
777 #endif
778     {
779       CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterOpen - avfilter_graph_parse");
780       return result;
781     }
782
783     m_dllAvFilter.avfilter_inout_free(&outputs);
784     m_dllAvFilter.avfilter_inout_free(&inputs);
785   }
786   else
787   {
788     if ((result = m_dllAvFilter.avfilter_link(m_pFilterIn, 0, m_pFilterOut, 0)) < 0)
789     {
790       CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterOpen - avfilter_link");
791       return result;
792     }
793   }
794
795   if ((result = m_dllAvFilter.avfilter_graph_config(m_pFilterGraph, NULL)) < 0)
796   {
797     CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterOpen - avfilter_graph_config");
798     return result;
799   }
800
801   return result;
802 }
803
804 void CDVDVideoCodecFFmpeg::FilterClose()
805 {
806 #if !defined(LIBAVFILTER_AVFRAME_BASED)
807   if(m_pBufferRef)
808   {
809     m_dllAvFilter.avfilter_unref_buffer(m_pBufferRef);
810     m_pBufferRef = NULL;
811   }
812 #endif
813
814   if (m_pFilterGraph)
815   {
816     m_dllAvFilter.avfilter_graph_free(&m_pFilterGraph);
817
818     // Disposed by above code
819     m_pFilterIn   = NULL;
820     m_pFilterOut  = NULL;
821   }
822 }
823
824 int CDVDVideoCodecFFmpeg::FilterProcess(AVFrame* frame)
825 {
826   int result;
827
828   if (frame)
829   {
830 #if defined(LIBAVFILTER_AVFRAME_BASED)
831     // API changed in:
832     // ffmpeg: commit 7e350379f87e7f74420b4813170fe808e2313911 (28 Nov 2012)
833     //         not released (post 1.2)
834     // libav: commit 7e350379f87e7f74420b4813170fe808e2313911 (28 Nov 2012)
835     //        release v9 (5 January 2013)
836     result = m_dllAvFilter.av_buffersrc_add_frame(m_pFilterIn, frame);
837 #else
838     // API changed in:
839     // ffmpeg: commit 7bac2a78c2241df4bcc1665703bb71afd9a3e692 (28 Apr 2012)
840     //         release 0.11 (25 May 2012)
841     result = m_dllAvFilter.av_buffersrc_add_frame(m_pFilterIn, frame, 0);
842 #endif
843     if (result < 0)
844     {
845       CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterProcess - av_buffersrc_add_frame");
846       return VC_ERROR;
847     }
848   }
849
850 #if defined(LIBAVFILTER_AVFRAME_BASED)
851   result = m_dllAvFilter.av_buffersink_get_frame(m_pFilterOut, m_pFilterFrame);
852
853   if(result  == AVERROR(EAGAIN) || result == AVERROR_EOF)
854     return VC_BUFFER;
855   else if(result < 0)
856   {
857     CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterProcess - av_buffersink_get_frame");
858     return VC_ERROR;
859   }
860
861   m_dllAvUtil.av_frame_unref(m_pFrame);
862   m_dllAvUtil.av_frame_move_ref(m_pFrame, m_pFilterFrame);
863
864   return VC_PICTURE;
865 #else
866   int frames;
867
868   if(m_pBufferRef)
869   {
870     m_dllAvFilter.avfilter_unref_buffer(m_pBufferRef);
871     m_pBufferRef = NULL;
872   }
873
874   if ((frames = m_dllAvFilter.av_buffersink_poll_frame(m_pFilterOut)) < 0)
875   {
876     CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterProcess - av_buffersink_poll_frame");
877     return VC_ERROR;
878   }
879
880   if (frames > 0)
881   {
882
883     result = m_dllAvFilter.av_buffersink_get_buffer_ref(m_pFilterOut, &m_pBufferRef, 0);
884     if(!m_pBufferRef || result < 0)
885     {
886       CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterProcess - cur_buf");
887       return VC_ERROR;
888     }
889
890     if(frame == NULL)
891       m_pFrame->reordered_opaque = 0;
892     else
893       m_pFrame->repeat_pict      = -(frames - 1);
894
895     m_pFrame->interlaced_frame = m_pBufferRef->video->interlaced;
896     m_pFrame->top_field_first  = m_pBufferRef->video->top_field_first;
897
898     memcpy(m_pFrame->linesize, m_pBufferRef->linesize, 4*sizeof(int));
899     memcpy(m_pFrame->data    , m_pBufferRef->data    , 4*sizeof(uint8_t*));
900
901     if(frames > 1)
902       return VC_PICTURE;
903     else
904       return VC_PICTURE | VC_BUFFER;
905   }
906
907   return VC_BUFFER;
908 #endif
909 }
910
911 unsigned CDVDVideoCodecFFmpeg::GetConvergeCount()
912 {
913   if(m_pHardware)
914     return m_iLastKeyframe;
915   else
916     return 0;
917 }
918
919 unsigned CDVDVideoCodecFFmpeg::GetAllowedReferences()
920 {
921   if(m_pHardware)
922     return m_pHardware->GetAllowedReferences();
923   else
924     return 0;
925 }