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