video_decode_thread.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. // ***********************************************************/
  2. // video_decode_thread.cpp
  3. //
  4. // Copy Right @ Steven Huang. All rights reserved.
  5. //
  6. // Video decode thread. This section includes queues
  7. // and dxva2 hardware transmit decoded frame.
  8. // ***********************************************************/
  9. #include "video_decode_thread.h"
  10. VideoDecodeThread::VideoDecodeThread(VideoState* pState)
  11. : m_pState(pState)
  12. {}
  13. VideoDecodeThread::~VideoDecodeThread() {}
  14. void VideoDecodeThread::stop()
  15. {
  16. m_exit = true;
  17. m_cv.notify_all();
  18. }
  19. void VideoDecodeThread::run()
  20. {
  21. assert(m_pState);
  22. VideoState* is = m_pState;
  23. AVFrame* frame = av_frame_alloc();
  24. AVFrame* sw_frame = av_frame_alloc();
  25. AVFrame* tmp_frame = nullptr;
  26. double pts;
  27. double duration;
  28. int ret;
  29. AVRational tb = is->video_st->time_base;
  30. AVRational frame_rate = av_guess_frame_rate(is->ic, is->video_st, nullptr);
  31. #if USE_AVFILTER_VIDEO
  32. AVFilterContext *filt_out = nullptr, *filt_in = nullptr;
  33. int last_w = 0;
  34. int last_h = 0;
  35. enum AVPixelFormat last_format = AV_PIX_FMT_NONE;
  36. int last_serial = -1;
  37. int last_vfilter_idx = 0;
  38. #endif
  39. if (!frame)
  40. return;
  41. for (;;) {
  42. if (m_exit)
  43. break;
  44. ret = get_video_frame(is, frame);
  45. if (ret < 0)
  46. goto the_end;
  47. if (!ret)
  48. continue;
  49. #if USE_AVFILTER_VIDEO
  50. if (last_w != frame->width || last_h != frame->height || last_format != frame->format
  51. || last_serial != is->viddec.pkt_serial || last_vfilter_idx != is->vfilter_idx
  52. || is->req_vfilter_reconfigure) {
  53. av_log(nullptr,
  54. AV_LOG_DEBUG,
  55. "Video frame changed from size:%dx%d format:%s serial:%d to "
  56. "size:%dx%d format:%s serial:%d\n",
  57. last_w,
  58. last_h,
  59. (const char*) av_x_if_null(av_get_pix_fmt_name(last_format), "none"),
  60. last_serial,
  61. frame->width,
  62. frame->height,
  63. (const char*) av_x_if_null(av_get_pix_fmt_name((AVPixelFormat) frame->format),
  64. "none"),
  65. is->viddec.pkt_serial);
  66. avfilter_graph_free(&is->vgraph);
  67. is->vgraph = avfilter_graph_alloc();
  68. if (!is->vgraph) {
  69. ret = AVERROR(ENOMEM);
  70. goto the_end;
  71. }
  72. is->vgraph->nb_threads = 0;
  73. if ((ret = configure_video_filters(is->vgraph, is, is->vfilters, frame)) < 0) {
  74. goto the_end;
  75. }
  76. filt_in = is->in_video_filter;
  77. filt_out = is->out_video_filter;
  78. last_w = frame->width;
  79. last_h = frame->height;
  80. last_format = (AVPixelFormat) frame->format;
  81. last_serial = is->viddec.pkt_serial;
  82. last_vfilter_idx = is->vfilter_idx;
  83. frame_rate = av_buffersink_get_frame_rate(filt_out);
  84. is->req_vfilter_reconfigure = 0;
  85. }
  86. ret = av_buffersrc_add_frame(filt_in, frame);
  87. if (ret < 0)
  88. goto the_end;
  89. while (ret >= 0) {
  90. is->frame_last_returned_time = av_gettime_relative() / 1000000.0;
  91. ret = av_buffersink_get_frame_flags(filt_out, frame, 0);
  92. if (ret < 0) {
  93. if (ret == AVERROR_EOF)
  94. is->viddec.finished = is->viddec.pkt_serial;
  95. ret = 0;
  96. break;
  97. }
  98. is->frame_last_filter_delay = av_gettime_relative() / 1000000.0
  99. - is->frame_last_returned_time;
  100. if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
  101. is->frame_last_filter_delay = 0;
  102. tb = av_buffersink_get_time_base(filt_out);
  103. #endif
  104. #if 0
  105. duration = (frame_rate.num && frame_rate.den ? av_q2d(AVRational{frame_rate.den, frame_rate.num}) : 0);
  106. pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
  107. ret = queue_picture(is, frame, pts, duration, frame->pkt_pos, is->viddec.pkt_serial);
  108. av_frame_unref(frame);
  109. #else
  110. tmp_frame = frame;
  111. if (frame->format == AV_PIX_FMT_DXVA2_VLD) // DXVA2 hardware decode frame
  112. {
  113. ret = av_hwframe_transfer_data(sw_frame, frame, 0);
  114. if (ret < 0) {
  115. av_log(nullptr,
  116. AV_LOG_WARNING,
  117. "Error transferring the data to system memory\n");
  118. goto the_end;
  119. }
  120. sw_frame->pts = frame->pts;
  121. sw_frame->pkt_dts = frame->pkt_dts;
  122. tmp_frame = sw_frame;
  123. }
  124. duration = (frame_rate.num && frame_rate.den ? av_q2d({frame_rate.den, frame_rate.num})
  125. : 0);
  126. pts = (frame->pts == AV_NOPTS_VALUE) ? NAN : frame->pts * av_q2d(tb);
  127. ret = queue_picture(is, tmp_frame, pts, duration, frame->pkt_pos, is->viddec.pkt_serial);
  128. av_frame_unref(tmp_frame);
  129. #endif
  130. #if USE_AVFILTER_VIDEO
  131. if (is->videoq.serial != is->viddec.pkt_serial)
  132. break;
  133. }
  134. #endif
  135. if (ret < 0)
  136. goto the_end;
  137. }
  138. the_end:
  139. #if USE_AVFILTER_VIDEO
  140. avfilter_graph_free(&is->vgraph);
  141. if (is->vfilters) {
  142. av_free(is->vfilters);
  143. is->vfilters = nullptr;
  144. }
  145. #endif
  146. av_frame_free(&frame);
  147. av_frame_free(&sw_frame);
  148. // 可加日志输出
  149. return;
  150. }