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