PageRenderTime 109ms CodeModel.GetById 13ms app.highlight 89ms RepoModel.GetById 1ms app.codeStats 0ms

/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecFFmpeg.cpp

http://github.com/xbmc/xbmc
C++ | 926 lines | 728 code | 143 blank | 55 comment | 177 complexity | 2ad76efa635b3e3f9a1dcc00de5b5437 MD5 | raw file
  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
 64using namespace boost;
 65
 66enum PixelFormat CDVDVideoCodecFFmpeg::GetFormat( struct AVCodecContext * avctx
 67                                                , const PixelFormat * fmt )
 68{
 69  CDVDVideoCodecFFmpeg* ctx  = (CDVDVideoCodecFFmpeg*)avctx->opaque;
 70
 71  if(!ctx->IsHardwareAllowed())
 72    return ctx->m_dllAvCodec.avcodec_default_get_format(avctx, fmt);
 73
 74  const PixelFormat * cur = fmt;
 75  while(*cur != PIX_FMT_NONE)
 76  {
 77#ifdef HAVE_LIBVDPAU
 78    if(VDPAU::CDecoder::IsVDPAUFormat(*cur) && CSettings::Get().GetBool("videoplayer.usevdpau"))
 79    {
 80      CLog::Log(LOGNOTICE,"CDVDVideoCodecFFmpeg::GetFormat - Creating VDPAU(%ix%i)", avctx->width, avctx->height);
 81      VDPAU::CDecoder* vdp = new VDPAU::CDecoder();
 82      if(vdp->Open(avctx, *cur, ctx->m_uSurfacesCount))
 83      {
 84        ctx->SetHardware(vdp);
 85        return *cur;
 86      }
 87      else
 88        vdp->Release();
 89    }
 90#endif
 91#ifdef HAS_DX
 92  if(DXVA::CDecoder::Supports(*cur) && CSettings::Get().GetBool("videoplayer.usedxva2"))
 93  {
 94    DXVA::CDecoder* dec = new DXVA::CDecoder();
 95    if(dec->Open(avctx, *cur, ctx->m_uSurfacesCount))
 96    {
 97      ctx->SetHardware(dec);
 98      return *cur;
 99    }
100    else
101      dec->Release();
102  }
103#endif
104#ifdef HAVE_LIBVA
105    // mpeg4 vaapi decoding is disabled
106    if(*cur == PIX_FMT_VAAPI_VLD && CSettings::Get().GetBool("videoplayer.usevaapi") 
107    && (avctx->codec_id != AV_CODEC_ID_MPEG4 || g_advancedSettings.m_videoAllowMpeg4VAAPI)) 
108    {
109      if (ctx->GetHardware() != NULL)
110      {
111        ctx->SetHardware(NULL);
112      }
113
114      VAAPI::CDecoder* dec = new VAAPI::CDecoder();
115      if(dec->Open(avctx, *cur, ctx->m_uSurfacesCount))
116      {
117        ctx->SetHardware(dec);
118        return *cur;
119      }
120      else
121        dec->Release();
122    }
123#endif
124
125#ifdef TARGET_DARWIN_OSX
126    if (*cur == AV_PIX_FMT_VDA_VLD && CSettings::Get().GetBool("videoplayer.usevda"))
127    {
128      VDA::CDecoder* dec = new VDA::CDecoder();
129      if(dec->Open(avctx, *cur, ctx->m_uSurfacesCount))
130      {
131        ctx->SetHardware(dec);
132        return *cur;
133      }
134      else
135        dec->Release();
136    }
137#endif
138    cur++;
139  }
140  return ctx->m_dllAvCodec.avcodec_default_get_format(avctx, fmt);
141}
142
143CDVDVideoCodecFFmpeg::CDVDVideoCodecFFmpeg() : CDVDVideoCodec()
144{
145  m_pCodecContext = NULL;
146  m_pFrame = NULL;
147  m_pFilterGraph  = NULL;
148  m_pFilterIn     = NULL;
149  m_pFilterOut    = NULL;
150#if defined(LIBAVFILTER_AVFRAME_BASED)
151  m_pFilterFrame  = NULL;
152#else
153  m_pBufferRef    = NULL;
154#endif
155
156  m_iPictureWidth = 0;
157  m_iPictureHeight = 0;
158
159  m_uSurfacesCount = 0;
160
161  m_iScreenWidth = 0;
162  m_iScreenHeight = 0;
163  m_iOrientation = 0;
164  m_bSoftware = false;
165  m_isHi10p = false;
166  m_pHardware = NULL;
167  m_iLastKeyframe = 0;
168  m_dts = DVD_NOPTS_VALUE;
169  m_started = false;
170}
171
172CDVDVideoCodecFFmpeg::~CDVDVideoCodecFFmpeg()
173{
174  Dispose();
175}
176
177bool CDVDVideoCodecFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options)
178{
179  AVCodec* pCodec;
180
181  if(!m_dllAvUtil.Load()
182  || !m_dllAvCodec.Load()
183  || !m_dllSwScale.Load()
184  || !m_dllPostProc.Load()
185  || !m_dllAvFilter.Load()
186  ) return false;
187
188  m_dllAvCodec.avcodec_register_all();
189  m_dllAvFilter.avfilter_register_all();
190
191  m_bSoftware     = hints.software;
192  m_iOrientation  = hints.orientation;
193
194  for(std::vector<ERenderFormat>::iterator it = options.m_formats.begin(); it != options.m_formats.end(); ++it)
195  {
196    m_formats.push_back((PixelFormat)CDVDCodecUtils::PixfmtFromEFormat(*it));
197    if(*it == RENDER_FMT_YUV420P)
198      m_formats.push_back(PIX_FMT_YUVJ420P);
199  }
200  m_formats.push_back(PIX_FMT_NONE); /* always add none to get a terminated list in ffmpeg world */
201
202  pCodec = NULL;
203  m_pCodecContext = NULL;
204
205  if (hints.codec == AV_CODEC_ID_H264)
206  {
207    switch(hints.profile)
208    {
209      case FF_PROFILE_H264_HIGH_10:
210      case FF_PROFILE_H264_HIGH_10_INTRA:
211      case FF_PROFILE_H264_HIGH_422:
212      case FF_PROFILE_H264_HIGH_422_INTRA:
213      case FF_PROFILE_H264_HIGH_444_PREDICTIVE:
214      case FF_PROFILE_H264_HIGH_444_INTRA:
215      case FF_PROFILE_H264_CAVLC_444:
216      // this is needed to not open the decoders
217      m_bSoftware = true;
218      // this we need to enable multithreading for hi10p via advancedsettings
219      m_isHi10p = true;
220      break;
221    }
222  }
223
224  if(pCodec == NULL)
225    pCodec = m_dllAvCodec.avcodec_find_decoder(hints.codec);
226
227  if(pCodec == NULL)
228  {
229    CLog::Log(LOGDEBUG,"CDVDVideoCodecFFmpeg::Open() Unable to find codec %d", hints.codec);
230    return false;
231  }
232
233  CLog::Log(LOGNOTICE,"CDVDVideoCodecFFmpeg::Open() Using codec: %s",pCodec->long_name ? pCodec->long_name : pCodec->name);
234
235  if(m_pCodecContext == NULL)
236    m_pCodecContext = m_dllAvCodec.avcodec_alloc_context3(pCodec);
237
238  m_pCodecContext->opaque = (void*)this;
239  m_pCodecContext->debug_mv = 0;
240  m_pCodecContext->debug = 0;
241  m_pCodecContext->workaround_bugs = FF_BUG_AUTODETECT;
242  m_pCodecContext->get_format = GetFormat;
243  m_pCodecContext->codec_tag = hints.codec_tag;
244  /* Only allow slice threading, since frame threading is more
245   * sensitive to changes in frame sizes, and it causes crashes
246   * during HW accell - so we unset it in this case.
247   *
248   * When we detect Hi10p and user did not disable hi10pmultithreading
249   * via advancedsettings.xml we keep the ffmpeg default thread type.
250   * */
251  if(m_isHi10p && !g_advancedSettings.m_videoDisableHi10pMultithreading)
252  {
253    CLog::Log(LOGDEBUG,"CDVDVideoCodecFFmpeg::Open() Keep default threading for Hi10p: %d",
254                        m_pCodecContext->thread_type);
255  }
256  else
257    m_pCodecContext->thread_type = FF_THREAD_SLICE;
258
259#if defined(TARGET_DARWIN_IOS)
260  // ffmpeg with enabled neon will crash and burn if this is enabled
261  m_pCodecContext->flags &= CODEC_FLAG_EMU_EDGE;
262#else
263  if (pCodec->id != AV_CODEC_ID_H264 && pCodec->capabilities & CODEC_CAP_DR1
264      && pCodec->id != AV_CODEC_ID_VP8
265     )
266    m_pCodecContext->flags |= CODEC_FLAG_EMU_EDGE;
267#endif
268
269  // if we don't do this, then some codecs seem to fail.
270  m_pCodecContext->coded_height = hints.height;
271  m_pCodecContext->coded_width = hints.width;
272  m_pCodecContext->bits_per_coded_sample = hints.bitsperpixel;
273
274  if( hints.extradata && hints.extrasize > 0 )
275  {
276    m_pCodecContext->extradata_size = hints.extrasize;
277    m_pCodecContext->extradata = (uint8_t*)m_dllAvUtil.av_mallocz(hints.extrasize + FF_INPUT_BUFFER_PADDING_SIZE);
278    memcpy(m_pCodecContext->extradata, hints.extradata, hints.extrasize);
279  }
280
281  // advanced setting override for skip loop filter (see avcodec.h for valid options)
282  // TODO: allow per video setting?
283  if (g_advancedSettings.m_iSkipLoopFilter != 0)
284  {
285    m_pCodecContext->skip_loop_filter = (AVDiscard)g_advancedSettings.m_iSkipLoopFilter;
286  }
287
288  // set any special options
289  for(std::vector<CDVDCodecOption>::iterator it = options.m_keys.begin(); it != options.m_keys.end(); ++it)
290  {
291    if (it->m_name == "surfaces")
292      m_uSurfacesCount = std::atoi(it->m_value.c_str());
293    else
294      m_dllAvUtil.av_opt_set(m_pCodecContext, it->m_name.c_str(), it->m_value.c_str(), 0);
295  }
296
297  int num_threads = std::min(8 /*MAX_THREADS*/, g_cpuInfo.getCPUCount());
298  if( num_threads > 1 && !hints.software && m_pHardware == NULL // thumbnail extraction fails when run threaded
299  && ( pCodec->id == AV_CODEC_ID_H264
300    || pCodec->id == AV_CODEC_ID_MPEG4 ))
301    m_pCodecContext->thread_count = num_threads;
302
303  if (m_dllAvCodec.avcodec_open2(m_pCodecContext, pCodec, NULL) < 0)
304  {
305    CLog::Log(LOGDEBUG,"CDVDVideoCodecFFmpeg::Open() Unable to open codec");
306    return false;
307  }
308
309  m_pFrame = m_dllAvCodec.avcodec_alloc_frame();
310  if (!m_pFrame) return false;
311
312#if defined(LIBAVFILTER_AVFRAME_BASED)
313  m_pFilterFrame = m_dllAvUtil.av_frame_alloc();
314  if (!m_pFilterFrame) return false;
315#endif
316
317  UpdateName();
318  return true;
319}
320
321void CDVDVideoCodecFFmpeg::Dispose()
322{
323  if (m_pFrame) m_dllAvUtil.av_free(m_pFrame);
324  m_pFrame = NULL;
325
326#if defined(LIBAVFILTER_AVFRAME_BASED)
327  m_dllAvUtil.av_frame_free(&m_pFilterFrame);
328#endif
329
330  if (m_pCodecContext)
331  {
332    if (m_pCodecContext->codec) m_dllAvCodec.avcodec_close(m_pCodecContext);
333    if (m_pCodecContext->extradata)
334    {
335      m_dllAvUtil.av_free(m_pCodecContext->extradata);
336      m_pCodecContext->extradata = NULL;
337      m_pCodecContext->extradata_size = 0;
338    }
339    m_dllAvUtil.av_free(m_pCodecContext);
340    m_pCodecContext = NULL;
341  }
342  SAFE_RELEASE(m_pHardware);
343
344  FilterClose();
345
346  m_dllAvCodec.Unload();
347  m_dllAvUtil.Unload();
348  m_dllAvFilter.Unload();
349  m_dllPostProc.Unload();
350}
351
352void CDVDVideoCodecFFmpeg::SetDropState(bool bDrop)
353{
354  if( m_pCodecContext )
355  {
356    // i don't know exactly how high this should be set
357    // couldn't find any good docs on it. think it varies
358    // from codec to codec on what it does
359
360    //  2 seem to be to high.. it causes video to be ruined on following images
361    if( bDrop )
362    {
363      m_pCodecContext->skip_frame = AVDISCARD_NONREF;
364      m_pCodecContext->skip_idct = AVDISCARD_NONREF;
365      m_pCodecContext->skip_loop_filter = AVDISCARD_NONREF;
366    }
367    else
368    {
369      m_pCodecContext->skip_frame = AVDISCARD_DEFAULT;
370      m_pCodecContext->skip_idct = AVDISCARD_DEFAULT;
371      m_pCodecContext->skip_loop_filter = AVDISCARD_DEFAULT;
372    }
373  }
374}
375
376unsigned int CDVDVideoCodecFFmpeg::SetFilters(unsigned int flags)
377{
378  m_filters_next.Empty();
379
380  if(m_pHardware)
381    return 0;
382
383  if(flags & FILTER_ROTATE)
384  {
385    switch(m_iOrientation)
386    {
387      case 90:
388        m_filters_next += "transpose=1";
389        break;
390      case 180:
391        m_filters_next += "vflip,hflip";
392        break;
393      case 270:  
394        m_filters_next += "transpose=2";
395        break;
396      default:
397        break;
398      }
399  }
400
401  if(flags & FILTER_DEINTERLACE_YADIF)
402  {
403    if(flags & FILTER_DEINTERLACE_HALFED)
404      m_filters_next = "yadif=0:-1";
405    else
406      m_filters_next = "yadif=1:-1";
407
408    if(flags & FILTER_DEINTERLACE_FLAGGED)
409      m_filters_next += ":1";
410
411    flags &= ~FILTER_DEINTERLACE_ANY | FILTER_DEINTERLACE_YADIF;
412  }
413
414  return flags;
415}
416
417union pts_union
418{
419  double  pts_d;
420  int64_t pts_i;
421};
422
423static int64_t pts_dtoi(double pts)
424{
425  pts_union u;
426  u.pts_d = pts;
427  return u.pts_i;
428}
429
430static double pts_itod(int64_t pts)
431{
432  pts_union u;
433  u.pts_i = pts;
434  return u.pts_d;
435}
436
437int CDVDVideoCodecFFmpeg::Decode(uint8_t* pData, int iSize, double dts, double pts)
438{
439  int iGotPicture = 0, len = 0;
440
441  if (!m_pCodecContext)
442    return VC_ERROR;
443
444  if(pData)
445    m_iLastKeyframe++;
446
447  shared_ptr<CSingleLock> lock;
448  if(m_pHardware)
449  {
450    CCriticalSection* section = m_pHardware->Section();
451    if(section)
452      lock = shared_ptr<CSingleLock>(new CSingleLock(*section));
453
454    int result;
455    if(pData)
456      result = m_pHardware->Check(m_pCodecContext);
457    else
458      result = m_pHardware->Decode(m_pCodecContext, NULL);
459
460    if(result)
461      return result;
462  }
463
464  if(m_pFilterGraph)
465  {
466    int result = 0;
467    if(pData == NULL)
468      result = FilterProcess(NULL);
469    if(result)
470      return result;
471  }
472
473  m_dts = dts;
474  m_pCodecContext->reordered_opaque = pts_dtoi(pts);
475
476  AVPacket avpkt;
477  m_dllAvCodec.av_init_packet(&avpkt);
478  avpkt.data = pData;
479  avpkt.size = iSize;
480  /* We lie, but this flag is only used by pngdec.c.
481   * Setting it correctly would allow CorePNG decoding. */
482  avpkt.flags = AV_PKT_FLAG_KEY;
483  len = m_dllAvCodec.avcodec_decode_video2(m_pCodecContext, m_pFrame, &iGotPicture, &avpkt);
484
485  if(m_iLastKeyframe < m_pCodecContext->has_b_frames + 2)
486    m_iLastKeyframe = m_pCodecContext->has_b_frames + 2;
487
488  if (len < 0)
489  {
490    CLog::Log(LOGERROR, "%s - avcodec_decode_video returned failure", __FUNCTION__);
491    return VC_ERROR;
492  }
493
494  if (!iGotPicture)
495    return VC_BUFFER;
496
497  if(m_pFrame->key_frame)
498  {
499    m_started = true;
500    m_iLastKeyframe = m_pCodecContext->has_b_frames + 2;
501  }
502
503  /* put a limit on convergence count to avoid huge mem usage on streams without keyframes */
504  if(m_iLastKeyframe > 300)
505    m_iLastKeyframe = 300;
506
507  /* h264 doesn't always have keyframes + won't output before first keyframe anyway */
508  if(m_pCodecContext->codec_id == AV_CODEC_ID_H264
509  || m_pCodecContext->codec_id == AV_CODEC_ID_SVQ3)
510    m_started = true;
511
512  if(m_pHardware == NULL)
513  {
514    bool need_scale = std::find( m_formats.begin()
515                               , m_formats.end()
516                               , m_pCodecContext->pix_fmt) == m_formats.end();
517
518    bool need_reopen  = false;
519    if(!m_filters.Equals(m_filters_next))
520      need_reopen = true;
521
522    if(m_pFilterIn)
523    {
524      if(m_pFilterIn->outputs[0]->format != m_pCodecContext->pix_fmt
525      || m_pFilterIn->outputs[0]->w      != m_pCodecContext->width
526      || m_pFilterIn->outputs[0]->h      != m_pCodecContext->height)
527        need_reopen = true;
528    }
529
530    // try to setup new filters
531    if (need_reopen || (need_scale && m_pFilterGraph == NULL))
532    {
533      m_filters = m_filters_next;
534
535      if(FilterOpen(m_filters, need_scale) < 0)
536        FilterClose();
537    }
538  }
539
540  int result;
541  if(m_pHardware)
542    result = m_pHardware->Decode(m_pCodecContext, m_pFrame);
543  else if(m_pFilterGraph)
544    result = FilterProcess(m_pFrame);
545  else
546    result = VC_PICTURE | VC_BUFFER;
547
548  if(result & VC_FLUSHED)
549    Reset();
550
551  return result;
552}
553
554void CDVDVideoCodecFFmpeg::Reset()
555{
556  m_started = false;
557  m_iLastKeyframe = m_pCodecContext->has_b_frames;
558  m_dllAvCodec.avcodec_flush_buffers(m_pCodecContext);
559
560  if (m_pHardware)
561    m_pHardware->Reset();
562
563  m_filters = "";
564  FilterClose();
565}
566
567bool CDVDVideoCodecFFmpeg::GetPictureCommon(DVDVideoPicture* pDvdVideoPicture)
568{
569  pDvdVideoPicture->iWidth = m_pFrame->width;
570  pDvdVideoPicture->iHeight = m_pFrame->height;
571
572#if !defined(LIBAVFILTER_AVFRAME_BASED)
573  if(m_pBufferRef)
574  {
575    pDvdVideoPicture->iWidth  = m_pBufferRef->video->w;
576    pDvdVideoPicture->iHeight = m_pBufferRef->video->h;
577  }
578#endif
579
580  /* crop of 10 pixels if demuxer asked it */
581  if(m_pCodecContext->coded_width  && m_pCodecContext->coded_width  < (int)pDvdVideoPicture->iWidth
582                                   && m_pCodecContext->coded_width  > (int)pDvdVideoPicture->iWidth  - 10)
583    pDvdVideoPicture->iWidth = m_pCodecContext->coded_width;
584
585  if(m_pCodecContext->coded_height && m_pCodecContext->coded_height < (int)pDvdVideoPicture->iHeight
586                                   && m_pCodecContext->coded_height > (int)pDvdVideoPicture->iHeight - 10)
587    pDvdVideoPicture->iHeight = m_pCodecContext->coded_height;
588
589  double aspect_ratio;
590
591  /* use variable in the frame */
592  AVRational pixel_aspect = m_pFrame->sample_aspect_ratio;
593#if !defined(LIBAVFILTER_AVFRAME_BASED)
594  if (m_pBufferRef)
595    pixel_aspect = m_pBufferRef->video->sample_aspect_ratio;
596#endif
597
598  if (pixel_aspect.num == 0)
599    aspect_ratio = 0;
600  else
601    aspect_ratio = av_q2d(pixel_aspect) * pDvdVideoPicture->iWidth / pDvdVideoPicture->iHeight;
602
603  if (aspect_ratio <= 0.0)
604    aspect_ratio = (float)pDvdVideoPicture->iWidth / (float)pDvdVideoPicture->iHeight;
605
606  /* XXX: we suppose the screen has a 1.0 pixel ratio */ // CDVDVideo will compensate it.
607  pDvdVideoPicture->iDisplayHeight = pDvdVideoPicture->iHeight;
608  pDvdVideoPicture->iDisplayWidth  = ((int)RINT(pDvdVideoPicture->iHeight * aspect_ratio)) & -3;
609  if (pDvdVideoPicture->iDisplayWidth > pDvdVideoPicture->iWidth)
610  {
611    pDvdVideoPicture->iDisplayWidth  = pDvdVideoPicture->iWidth;
612    pDvdVideoPicture->iDisplayHeight = ((int)RINT(pDvdVideoPicture->iWidth / aspect_ratio)) & -3;
613  }
614
615
616  pDvdVideoPicture->pts = DVD_NOPTS_VALUE;
617
618  if (!m_pFrame)
619    return false;
620
621  AVDictionaryEntry * entry = m_dllAvUtil.av_dict_get(m_dllAvCodec.av_frame_get_metadata(m_pFrame), "stereo_mode", NULL, 0);
622  if(entry && entry->value)
623  {
624    strncpy(pDvdVideoPicture->stereo_mode, (const char*)entry->value, sizeof(pDvdVideoPicture->stereo_mode));
625    pDvdVideoPicture->stereo_mode[sizeof(pDvdVideoPicture->stereo_mode)-1] = '\0';
626  }
627
628  pDvdVideoPicture->iRepeatPicture = 0.5 * m_pFrame->repeat_pict;
629  pDvdVideoPicture->iFlags = DVP_FLAG_ALLOCATED;
630  pDvdVideoPicture->iFlags |= m_pFrame->interlaced_frame ? DVP_FLAG_INTERLACED : 0;
631  pDvdVideoPicture->iFlags |= m_pFrame->top_field_first ? DVP_FLAG_TOP_FIELD_FIRST: 0;
632
633  pDvdVideoPicture->chroma_position = m_pCodecContext->chroma_sample_location;
634  pDvdVideoPicture->color_primaries = m_pCodecContext->color_primaries;
635  pDvdVideoPicture->color_transfer = m_pCodecContext->color_trc;
636  if(m_pCodecContext->color_range == AVCOL_RANGE_JPEG
637  || m_pCodecContext->pix_fmt     == PIX_FMT_YUVJ420P)
638    pDvdVideoPicture->color_range = 1;
639  else
640    pDvdVideoPicture->color_range = 0;
641
642  pDvdVideoPicture->qscale_table = m_pFrame->qscale_table;
643  pDvdVideoPicture->qscale_stride = m_pFrame->qstride;
644
645  switch (m_pFrame->qscale_type) {
646  case FF_QSCALE_TYPE_MPEG1:
647    pDvdVideoPicture->qscale_type = DVP_QSCALE_MPEG1;
648    break;
649  case FF_QSCALE_TYPE_MPEG2:
650    pDvdVideoPicture->qscale_type = DVP_QSCALE_MPEG2;
651    break;
652  case FF_QSCALE_TYPE_H264:
653    pDvdVideoPicture->qscale_type = DVP_QSCALE_H264;
654    break;
655  default:
656    pDvdVideoPicture->qscale_type = DVP_QSCALE_UNKNOWN;
657  }
658
659  pDvdVideoPicture->dts = m_dts;
660  m_dts = DVD_NOPTS_VALUE;
661  if (m_pFrame->reordered_opaque)
662    pDvdVideoPicture->pts = pts_itod(m_pFrame->reordered_opaque);
663  else
664    pDvdVideoPicture->pts = DVD_NOPTS_VALUE;
665
666  if(!m_started)
667    pDvdVideoPicture->iFlags |= DVP_FLAG_DROPPED;
668
669  return true;
670}
671
672bool CDVDVideoCodecFFmpeg::GetPicture(DVDVideoPicture* pDvdVideoPicture)
673{
674  if(m_pHardware)
675    return m_pHardware->GetPicture(m_pCodecContext, m_pFrame, pDvdVideoPicture);
676
677  if(!GetPictureCommon(pDvdVideoPicture))
678    return false;
679
680  {
681    for (int i = 0; i < 4; i++)
682      pDvdVideoPicture->data[i]      = m_pFrame->data[i];
683    for (int i = 0; i < 4; i++)
684      pDvdVideoPicture->iLineSize[i] = m_pFrame->linesize[i];
685  }
686
687  pDvdVideoPicture->iFlags |= pDvdVideoPicture->data[0] ? 0 : DVP_FLAG_DROPPED;
688  pDvdVideoPicture->extended_format = 0;
689
690  PixelFormat pix_fmt;
691#if !defined(LIBAVFILTER_AVFRAME_BASED)
692  if(m_pBufferRef)
693    pix_fmt = (PixelFormat)m_pBufferRef->format;
694  else
695#endif
696    pix_fmt = (PixelFormat)m_pFrame->format;
697
698  pDvdVideoPicture->format = CDVDCodecUtils::EFormatFromPixfmt(pix_fmt);
699  return true;
700}
701
702int CDVDVideoCodecFFmpeg::FilterOpen(const CStdString& filters, bool scale)
703{
704  int result;
705  AVBufferSinkParams *buffersink_params;
706
707  if (m_pFilterGraph)
708    FilterClose();
709
710  if (filters.IsEmpty() && !scale)
711    return 0;
712
713  if (m_pHardware)
714  {
715    CLog::Log(LOGWARNING, "CDVDVideoCodecFFmpeg::FilterOpen - skipped opening filters on hardware decode");
716    return 0;
717  }
718
719  if (!(m_pFilterGraph = m_dllAvFilter.avfilter_graph_alloc()))
720  {
721    CLog::Log(LOGERROR, "CDVDVideoCodecFFmpeg::FilterOpen - unable to alloc filter graph");
722    return -1;
723  }
724
725  AVFilter* srcFilter = m_dllAvFilter.avfilter_get_by_name("buffer");
726  AVFilter* outFilter = m_dllAvFilter.avfilter_get_by_name("buffersink"); // should be last filter in the graph for now
727
728  CStdString args;
729
730  args.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
805void 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
825int 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
912unsigned CDVDVideoCodecFFmpeg::GetConvergeCount()
913{
914  if(m_pHardware)
915    return m_iLastKeyframe;
916  else
917    return 0;
918}
919
920unsigned CDVDVideoCodecFFmpeg::GetAllowedReferences()
921{
922  if(m_pHardware)
923    return m_pHardware->GetAllowedReferences();
924  else
925    return 0;
926}