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

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