Advertisement
Guest User

ScanStreams.patch

a guest
Dec 13th, 2012
35
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 20.99 KB | None | 0 0
  1. diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp
  2. index 61e4a31..9be6b71 100644
  3. --- a/mythtv/libs/libmythtv/avformatdecoder.cpp
  4. +++ b/mythtv/libs/libmythtv/avformatdecoder.cpp
  5. @@ -1819,16 +1819,6 @@ int AvFormatDecoder::ScanStreams(bool novideo)
  6. continue;
  7. }
  8.  
  9. - // Ignore stream with attachment
  10. - if (ic->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC)
  11. - {
  12. - LOG(VB_PLAYBACK, LOG_INFO, LOC +
  13. - QString("Skipping stream #%1").arg(i));
  14. - continue;
  15. - }
  16. -
  17. - codec_is_mpeg = CODEC_IS_FFMPEG_MPEG(enc->codec_id);
  18. -
  19. // ffmpeg does not return a bitrate for several codecs and
  20. // formats. Forcing it to 500000 ensures the ringbuffer does not
  21. // use optimisations for low bitrate (audio and data) streams.
  22. @@ -1837,158 +1827,7 @@ int AvFormatDecoder::ScanStreams(bool novideo)
  23. enc->bit_rate = 500000;
  24. unknownbitrate = true;
  25. }
  26. -
  27. - StreamInfo si(i, 0, 0, 0, 0);
  28. - tracks[kTrackTypeVideo].push_back(si);
  29. bitrate += enc->bit_rate;
  30. - if (novideo)
  31. - break;
  32. -
  33. - delete private_dec;
  34. - private_dec = NULL;
  35. - m_h264_parser->Reset();
  36. -
  37. - QSize dim = get_video_dim(*enc);
  38. - uint width = max(dim.width(), 16);
  39. - uint height = max(dim.height(), 16);
  40. - QString dec = "ffmpeg";
  41. - uint thread_count = 1;
  42. -
  43. - if (!is_db_ignored)
  44. - {
  45. - VideoDisplayProfile vdp;
  46. - vdp.SetInput(QSize(width, height));
  47. - dec = vdp.GetDecoder();
  48. - thread_count = vdp.GetMaxCPUs();
  49. - bool skip_loop_filter = vdp.IsSkipLoopEnabled();
  50. - if (!skip_loop_filter)
  51. - {
  52. - enc->skip_loop_filter = AVDISCARD_NONKEY;
  53. - }
  54. - }
  55. -
  56. - video_codec_id = kCodec_NONE;
  57. - int version = mpeg_version(enc->codec_id);
  58. - if (version)
  59. - video_codec_id = (MythCodecID)(kCodec_MPEG1 + version - 1);
  60. -
  61. - if (version)
  62. - {
  63. -#if defined(USING_VDPAU)
  64. - // HACK -- begin
  65. - // Force MPEG2 decoder on MPEG1 streams.
  66. - // Needed for broken transmitters which mark
  67. - // MPEG2 streams as MPEG1 streams, and should
  68. - // be harmless for unbroken ones.
  69. - if (enc->codec_id == AV_CODEC_ID_MPEG1VIDEO)
  70. - enc->codec_id = AV_CODEC_ID_MPEG2VIDEO;
  71. - // HACK -- end
  72. -#endif // USING_VDPAU
  73. -#ifdef USING_VDPAU
  74. - MythCodecID vdpau_mcid;
  75. - vdpau_mcid = VideoOutputVDPAU::GetBestSupportedCodec(
  76. - width, height, dec,
  77. - mpeg_version(enc->codec_id),
  78. - !FlagIsSet(kDecodeAllowGPU));
  79. -
  80. - if (vdpau_mcid >= video_codec_id)
  81. - {
  82. - enc->codec_id = (CodecID) myth2av_codecid(vdpau_mcid);
  83. - video_codec_id = vdpau_mcid;
  84. - }
  85. -#endif // USING_VDPAU
  86. -#ifdef USING_GLVAAPI
  87. - MythCodecID vaapi_mcid;
  88. - PixelFormat pix_fmt = PIX_FMT_YUV420P;
  89. - vaapi_mcid = VideoOutputOpenGLVAAPI::GetBestSupportedCodec(
  90. - width, height, dec, mpeg_version(enc->codec_id),
  91. - !FlagIsSet(kDecodeAllowGPU), pix_fmt);
  92. -
  93. - if (vaapi_mcid >= video_codec_id)
  94. - {
  95. - enc->codec_id = (CodecID)myth2av_codecid(vaapi_mcid);
  96. - video_codec_id = vaapi_mcid;
  97. - if (FlagIsSet(kDecodeAllowGPU) &&
  98. - codec_is_vaapi(video_codec_id))
  99. - {
  100. - enc->pix_fmt = pix_fmt;
  101. - }
  102. - }
  103. -#endif // USING_GLVAAPI
  104. -#ifdef USING_DXVA2
  105. - MythCodecID dxva2_mcid;
  106. - PixelFormat pix_fmt = PIX_FMT_YUV420P;
  107. - dxva2_mcid = VideoOutputD3D::GetBestSupportedCodec(
  108. - width, height, dec, mpeg_version(enc->codec_id),
  109. - !FlagIsSet(kDecodeAllowGPU), pix_fmt);
  110. -
  111. - if (dxva2_mcid >= video_codec_id)
  112. - {
  113. - enc->codec_id = (CodecID)myth2av_codecid(dxva2_mcid);
  114. - video_codec_id = dxva2_mcid;
  115. - if (FlagIsSet(kDecodeAllowGPU) &&
  116. - codec_is_dxva2(video_codec_id))
  117. - {
  118. - enc->pix_fmt = pix_fmt;
  119. - }
  120. - }
  121. -#endif // USING_DXVA2
  122. - }
  123. -
  124. - // default to mpeg2
  125. - if (video_codec_id == kCodec_NONE)
  126. - {
  127. - LOG(VB_GENERAL, LOG_ERR, LOC +
  128. - "Unknown video codec - defaulting to MPEG2");
  129. - video_codec_id = kCodec_MPEG2;
  130. - }
  131. -
  132. - if (enc->codec)
  133. - {
  134. - LOG(VB_GENERAL, LOG_WARNING, LOC +
  135. - QString("Warning, video codec 0x%1 id(%2) type (%3) "
  136. - "already open.")
  137. - .arg((uint64_t)enc,0,16)
  138. - .arg(ff_codec_id_string(enc->codec_id))
  139. - .arg(ff_codec_type_string(enc->codec_type)));
  140. - }
  141. -
  142. - // Set the default stream to the stream
  143. - // that is found first in the PMT
  144. - if (selectedTrack[kTrackTypeVideo].av_stream_index < 0)
  145. - selectedTrack[kTrackTypeVideo] = si;
  146. -
  147. - // Use a PrivateDecoder if allowed in playerFlags AND matched
  148. - // via the decoder name
  149. - if (selectedTrack[kTrackTypeVideo].av_stream_index == (int) i)
  150. - {
  151. - private_dec = PrivateDecoder::Create(dec, playerFlags, enc);
  152. - if (private_dec)
  153. - thread_count = 1;
  154. - }
  155. -
  156. - if (!codec_is_std(video_codec_id))
  157. - thread_count = 1;
  158. -
  159. - if (FlagIsSet(kDecodeSingleThreaded))
  160. - thread_count = 1;
  161. -
  162. - LOG(VB_PLAYBACK, LOG_INFO, LOC +
  163. - QString("Using %1 CPUs for decoding")
  164. - .arg(HAVE_THREADS ? thread_count : 1));
  165. -
  166. - if (HAVE_THREADS)
  167. - enc->thread_count = thread_count;
  168. -
  169. - InitVideoCodec(ic->streams[i], enc,
  170. - selectedTrack[kTrackTypeVideo].av_stream_index == (int) i);
  171. -
  172. - ScanATSCCaptionStreams(i);
  173. - UpdateATSCCaptionTracks();
  174. -
  175. - LOG(VB_PLAYBACK, LOG_INFO, LOC +
  176. - QString("Using %1 for video decoding")
  177. - .arg(GetCodecDecoderName()));
  178.  
  179. break;
  180. }
  181. @@ -2054,7 +1893,6 @@ int AvFormatDecoder::ScanStreams(bool novideo)
  182. }
  183.  
  184. if (enc->codec_type != AVMEDIA_TYPE_AUDIO &&
  185. - enc->codec_type != AVMEDIA_TYPE_VIDEO &&
  186. enc->codec_type != AVMEDIA_TYPE_SUBTITLE)
  187. continue;
  188.  
  189. @@ -2118,39 +1956,11 @@ int AvFormatDecoder::ScanStreams(bool novideo)
  190. if (!codec)
  191. continue;
  192. }
  193. - // select vdpau capable decoder if needed
  194. - else if (enc->codec_type == AVMEDIA_TYPE_VIDEO &&
  195. - codec_is_vdpau(video_codec_id) && !CODEC_IS_VDPAU(codec))
  196. - {
  197. - codec = find_vdpau_decoder(codec, enc->codec_id);
  198. - }
  199.  
  200. if (!enc->codec)
  201. {
  202. - QMutexLocker locker(avcodeclock);
  203. -
  204. - int open_val = avcodec_open2(enc, codec, NULL);
  205. - if (open_val < 0)
  206. - {
  207. - LOG(VB_GENERAL, LOG_ERR, LOC +
  208. - QString("Could not open codec 0x%1, id(%2) type(%3) "
  209. - "aborting. reason %4").arg((uint64_t)enc,0,16)
  210. - .arg(ff_codec_id_string(enc->codec_id))
  211. - .arg(ff_codec_type_string(enc->codec_type))
  212. - .arg(open_val));
  213. - //av_close_input_file(ic); // causes segfault
  214. - ic = NULL;
  215. - scanerror = -1;
  216. - break;
  217. - }
  218. - else
  219. - {
  220. - LOG(VB_GENERAL, LOG_INFO, LOC +
  221. - QString("Opened codec 0x%1, id(%2) type(%3)")
  222. - .arg((uint64_t)enc,0,16)
  223. - .arg(ff_codec_id_string(enc->codec_id))
  224. - .arg(ff_codec_type_string(enc->codec_type)));
  225. - }
  226. + if (OpenAVCodec(enc, codec) < 0)
  227. + continue;
  228. }
  229.  
  230. if (enc->codec_type == AVMEDIA_TYPE_SUBTITLE)
  231. @@ -2213,6 +2023,213 @@ int AvFormatDecoder::ScanStreams(bool novideo)
  232. }
  233. }
  234.  
  235. + // Now find best video track to play
  236. + if (!novideo && ic)
  237. + {
  238. + for(;;)
  239. + {
  240. + AVCodec *codec = NULL;
  241. + selectedTrack[kTrackTypeVideo].av_stream_index == -1;
  242. + LOG(VB_PLAYBACK, LOG_INFO, LOC +
  243. + "Trying to select best video track");
  244. +
  245. + /*
  246. + * Find the "best" stream in the file.
  247. + *
  248. + * The best stream is determined according to various heuristics as
  249. + * the most likely to be what the user expects. If the decoder parameter
  250. + * is non-NULL, av_find_best_stream will find the default decoder
  251. + * for the stream's codec; streams for which no decoder can be found
  252. + * are ignored.
  253. + *
  254. + * If av_find_best_stream returns successfully and decoder_ret is not NULL,
  255. + * then *decoder_ret is guaranteed to be set to a valid AVCodec.
  256. + */
  257. + int selTrack = av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
  258. + -1, -1, &codec, 0);
  259. +
  260. + if (selTrack < 0)
  261. + {
  262. + LOG(VB_PLAYBACK, LOG_INFO, LOC +
  263. + "No video track found/selected.");
  264. + break;
  265. + }
  266. +
  267. + AVCodecContext *enc = ic->streams[selTrack]->codec;
  268. + StreamInfo si(selTrack, 0, 0, 0, 0);
  269. +
  270. + tracks[kTrackTypeVideo].push_back(si);
  271. + selectedTrack[kTrackTypeVideo] = si;
  272. +
  273. + LOG(VB_PLAYBACK, LOG_INFO, LOC +
  274. + QString("Selected track #%1 (id 0x%2 codec id %3, "
  275. + "type %4, bitrate %5 at 0x%6)")
  276. + .arg(selTrack).arg((uint64_t)ic->streams[selTrack]->id,0,16)
  277. + .arg(ff_codec_id_string(enc->codec_id))
  278. + .arg(ff_codec_type_string(enc->codec_type))
  279. + .arg(enc->bit_rate).arg((uint64_t)ic->streams[selTrack],0,16));
  280. +
  281. + codec_is_mpeg = CODEC_IS_FFMPEG_MPEG(enc->codec_id);
  282. +
  283. + delete private_dec;
  284. + private_dec = NULL;
  285. + m_h264_parser->Reset();
  286. +
  287. + QSize dim = get_video_dim(*enc);
  288. + uint width = max(dim.width(), 16);
  289. + uint height = max(dim.height(), 16);
  290. + QString dec = "ffmpeg";
  291. + uint thread_count = 1;
  292. +
  293. + if (!is_db_ignored)
  294. + {
  295. + VideoDisplayProfile vdp;
  296. + vdp.SetInput(QSize(width, height));
  297. + dec = vdp.GetDecoder();
  298. + thread_count = vdp.GetMaxCPUs();
  299. + bool skip_loop_filter = vdp.IsSkipLoopEnabled();
  300. + if (!skip_loop_filter)
  301. + {
  302. + enc->skip_loop_filter = AVDISCARD_NONKEY;
  303. + }
  304. + }
  305. +
  306. + video_codec_id = kCodec_NONE;
  307. + int version = mpeg_version(enc->codec_id);
  308. + if (version)
  309. + video_codec_id = (MythCodecID)(kCodec_MPEG1 + version - 1);
  310. +
  311. + if (version)
  312. + {
  313. +#if defined(USING_VDPAU)
  314. + // HACK -- begin
  315. + // Force MPEG2 decoder on MPEG1 streams.
  316. + // Needed for broken transmitters which mark
  317. + // MPEG2 streams as MPEG1 streams, and should
  318. + // be harmless for unbroken ones.
  319. + if (enc->codec_id == AV_CODEC_ID_MPEG1VIDEO)
  320. + enc->codec_id = AV_CODEC_ID_MPEG2VIDEO;
  321. + // HACK -- end
  322. +#endif // USING_VDPAU
  323. +#ifdef USING_VDPAU
  324. + MythCodecID vdpau_mcid;
  325. + vdpau_mcid =
  326. + VideoOutputVDPAU::GetBestSupportedCodec(width, height, dec,
  327. + mpeg_version(enc->codec_id),
  328. + !FlagIsSet(kDecodeAllowGPU));
  329. +
  330. + if (vdpau_mcid >= video_codec_id)
  331. + {
  332. + enc->codec_id = (CodecID) myth2av_codecid(vdpau_mcid);
  333. + video_codec_id = vdpau_mcid;
  334. + }
  335. +#endif // USING_VDPAU
  336. +#ifdef USING_GLVAAPI
  337. + MythCodecID vaapi_mcid;
  338. + PixelFormat pix_fmt = PIX_FMT_YUV420P;
  339. + vaapi_mcid =
  340. + VideoOutputOpenGLVAAPI::GetBestSupportedCodec(width, height, dec,
  341. + mpeg_version(enc->codec_id),
  342. + !FlagIsSet(kDecodeAllowGPU),
  343. + pix_fmt);
  344. +
  345. + if (vaapi_mcid >= video_codec_id)
  346. + {
  347. + enc->codec_id = (CodecID)myth2av_codecid(vaapi_mcid);
  348. + video_codec_id = vaapi_mcid;
  349. + if (FlagIsSet(kDecodeAllowGPU) &&
  350. + codec_is_vaapi(video_codec_id))
  351. + {
  352. + enc->pix_fmt = pix_fmt;
  353. + }
  354. + }
  355. +#endif // USING_GLVAAPI
  356. +#ifdef USING_DXVA2
  357. + MythCodecID dxva2_mcid;
  358. + PixelFormat pix_fmt = PIX_FMT_YUV420P;
  359. + dxva2_mcid = VideoOutputD3D::GetBestSupportedCodec(
  360. + width, height, dec, mpeg_version(enc->codec_id),
  361. + !FlagIsSet(kDecodeAllowGPU), pix_fmt);
  362. +
  363. + if (dxva2_mcid >= video_codec_id)
  364. + {
  365. + enc->codec_id = (CodecID)myth2av_codecid(dxva2_mcid);
  366. + video_codec_id = dxva2_mcid;
  367. + if (FlagIsSet(kDecodeAllowGPU) &&
  368. + codec_is_dxva2(video_codec_id))
  369. + {
  370. + enc->pix_fmt = pix_fmt;
  371. + }
  372. + }
  373. +#endif // USING_DXVA2
  374. + }
  375. +
  376. + // default to mpeg2
  377. + if (video_codec_id == kCodec_NONE)
  378. + {
  379. + LOG(VB_GENERAL, LOG_ERR, LOC +
  380. + "Unknown video codec - defaulting to MPEG2");
  381. + video_codec_id = kCodec_MPEG2;
  382. + }
  383. +
  384. + if (enc->codec)
  385. + {
  386. + LOG(VB_GENERAL, LOG_WARNING, LOC +
  387. + QString("Warning, video codec 0x%1 id(%2) type (%3) "
  388. + "already open.")
  389. + .arg((uint64_t)enc,0,16)
  390. + .arg(ff_codec_id_string(enc->codec_id))
  391. + .arg(ff_codec_type_string(enc->codec_type)));
  392. + }
  393. +
  394. + // Use a PrivateDecoder if allowed in playerFlags AND matched
  395. + // via the decoder name
  396. + private_dec = PrivateDecoder::Create(dec, playerFlags, enc);
  397. + if (private_dec)
  398. + thread_count = 1;
  399. +
  400. + if (!codec_is_std(video_codec_id))
  401. + thread_count = 1;
  402. +
  403. + if (FlagIsSet(kDecodeSingleThreaded))
  404. + thread_count = 1;
  405. +
  406. + LOG(VB_PLAYBACK, LOG_INFO, LOC +
  407. + QString("Using %1 CPUs for decoding")
  408. + .arg(HAVE_THREADS ? thread_count : 1));
  409. +
  410. + if (HAVE_THREADS)
  411. + enc->thread_count = thread_count;
  412. +
  413. + InitVideoCodec(ic->streams[selTrack], enc, true);
  414. +
  415. + ScanATSCCaptionStreams(selTrack);
  416. + UpdateATSCCaptionTracks();
  417. +
  418. + LOG(VB_PLAYBACK, LOG_INFO, LOC +
  419. + QString("Using %1 for video decoding")
  420. + .arg(GetCodecDecoderName()));
  421. +
  422. + if (codec_is_vdpau(video_codec_id) && !CODEC_IS_VDPAU(codec))
  423. + {
  424. + codec = find_vdpau_decoder(codec, enc->codec_id);
  425. + }
  426. +
  427. + if (!enc->codec)
  428. + {
  429. + QMutexLocker locker(avcodeclock);
  430. +
  431. + if (OpenAVCodec(enc, codec) < 0)
  432. + {
  433. + scanerror = -1;
  434. + break;
  435. + }
  436. + }
  437. +
  438. + break;
  439. + }
  440. + }
  441. +
  442. if (ic && ((uint)ic->bit_rate > bitrate))
  443. bitrate = (uint)ic->bit_rate;
  444.  
  445. @@ -2249,8 +2266,6 @@ int AvFormatDecoder::ScanStreams(bool novideo)
  446. // video params are set properly
  447. if (selectedTrack[kTrackTypeVideo].av_stream_index == -1)
  448. {
  449. - LOG(VB_PLAYBACK, LOG_INFO, LOC +
  450. - QString("No video track found/selected."));
  451. QString tvformat = gCoreContext->GetSetting("TVFormat").toLower();
  452. if (tvformat == "ntsc" || tvformat == "ntsc-jp" ||
  453. tvformat == "pal-m" || tvformat == "atsc")
  454. @@ -2273,6 +2288,35 @@ int AvFormatDecoder::ScanStreams(bool novideo)
  455. return scanerror;
  456. }
  457.  
  458. +bool AvFormatDecoder::OpenAVCodec(AVCodecContext *avctx, const AVCodec *codec)
  459. +{
  460. + QMutexLocker locker(avcodeclock);
  461. +
  462. + int ret = avcodec_open2(avctx, codec, NULL);
  463. + if (ret < 0)
  464. + {
  465. + char error[AV_ERROR_MAX_STRING_SIZE];
  466. +
  467. + av_make_error_string(error, sizeof(error), ret);
  468. + LOG(VB_GENERAL, LOG_ERR, LOC +
  469. + QString("Could not open codec 0x%1, id(%2) type(%3) "
  470. + "ignoring. reason %4").arg((uint64_t)avctx,0,16)
  471. + .arg(ff_codec_id_string(avctx->codec_id))
  472. + .arg(ff_codec_type_string(avctx->codec_type))
  473. + .arg(error));
  474. + return false;
  475. + }
  476. + else
  477. + {
  478. + LOG(VB_GENERAL, LOG_INFO, LOC +
  479. + QString("Opened codec 0x%1, id(%2) type(%3)")
  480. + .arg((uint64_t)avctx,0,16)
  481. + .arg(ff_codec_id_string(avctx->codec_id))
  482. + .arg(ff_codec_type_string(avctx->codec_type)));
  483. + return true;
  484. + }
  485. +}
  486. +
  487. void AvFormatDecoder::UpdateFramesPlayed(void)
  488. {
  489. return DecoderBase::UpdateFramesPlayed();
  490. @@ -4628,12 +4672,15 @@ bool AvFormatDecoder::GetFrame(DecodeType decodetype)
  491.  
  492. if (!curstream->codec->codec)
  493. {
  494. - LOG(VB_PLAYBACK, LOG_ERR, LOC +
  495. - QString("No codec for stream index %1, type(%2) id(%3:%4)")
  496. - .arg(pkt->stream_index)
  497. - .arg(ff_codec_type_string(codec_type))
  498. - .arg(ff_codec_id_string(curstream->codec->codec_id))
  499. - .arg(curstream->codec->codec_id));
  500. + if (codec_type != AVMEDIA_TYPE_VIDEO)
  501. + {
  502. + LOG(VB_PLAYBACK, LOG_ERR, LOC +
  503. + QString("No codec for stream index %1, type(%2) id(%3:%4)")
  504. + .arg(pkt->stream_index)
  505. + .arg(ff_codec_type_string(codec_type))
  506. + .arg(ff_codec_id_string(curstream->codec->codec_id))
  507. + .arg(curstream->codec->codec_id));
  508. + }
  509. av_free_packet(pkt);
  510. continue;
  511. }
  512. diff --git a/mythtv/libs/libmythtv/avformatdecoder.h b/mythtv/libs/libmythtv/avformatdecoder.h
  513. index 8cd7d12..8259e2c 100644
  514. --- a/mythtv/libs/libmythtv/avformatdecoder.h
  515. +++ b/mythtv/libs/libmythtv/avformatdecoder.h
  516. @@ -251,6 +251,7 @@ class AvFormatDecoder : public DecoderBase
  517. bool HasVideo(const AVFormatContext *ic);
  518. float normalized_fps(AVStream *stream, AVCodecContext *enc);
  519. void av_update_stream_timings_video(AVFormatContext *ic);
  520. + bool OpenAVCodec(AVCodecContext *avctx, const AVCodec *codec);
  521.  
  522. virtual void UpdateFramesPlayed(void);
  523. virtual bool DoRewindSeek(long long desiredFrame);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement