198.patch 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. From 67be4abd22b726e277c4b67bfb3abf5a65cfd9b5 Mon Sep 17 00:00:00 2001
  2. From: Zane van Iperen <zane@zanevaniperen.com>
  3. Date: Mon, 15 Mar 2021 17:23:23 +1000
  4. Subject: [PATCH 1/9] lib/moviedecoder: remove unused variable
  5. ---
  6. libffmpegthumbnailer/moviedecoder.cpp | 2 --
  7. 1 file changed, 2 deletions(-)
  8. diff --git a/libffmpegthumbnailer/moviedecoder.cpp b/libffmpegthumbnailer/moviedecoder.cpp
  9. index 290e212..aa44adf 100644
  10. --- a/libffmpegthumbnailer/moviedecoder.cpp
  11. +++ b/libffmpegthumbnailer/moviedecoder.cpp
  12. @@ -570,8 +570,6 @@ bool MovieDecoder::getVideoPacket()
  13. bool framesAvailable = true;
  14. bool frameDecoded = false;
  15. - int attempts = 0;
  16. -
  17. if (m_pPacket)
  18. {
  19. av_packet_unref(m_pPacket);
  20. From 66f64668e7a063e790813c7733ca438ab112af89 Mon Sep 17 00:00:00 2001
  21. From: Zane van Iperen <zane@zanevaniperen.com>
  22. Date: Mon, 15 Mar 2021 17:42:07 +1000
  23. Subject: [PATCH 2/9] lib/moviedecoder: clang-tidy fixes
  24. ---
  25. libffmpegthumbnailer/moviedecoder.cpp | 4 ++--
  26. 1 file changed, 2 insertions(+), 2 deletions(-)
  27. diff --git a/libffmpegthumbnailer/moviedecoder.cpp b/libffmpegthumbnailer/moviedecoder.cpp
  28. index aa44adf..79c950b 100644
  29. --- a/libffmpegthumbnailer/moviedecoder.cpp
  30. +++ b/libffmpegthumbnailer/moviedecoder.cpp
  31. @@ -503,12 +503,12 @@ void MovieDecoder::seek(int timeInSeconds)
  32. avcodec_flush_buffers(m_pFormatContext->streams[m_VideoStream]->codec);
  33. int keyFrameAttempts = 0;
  34. - bool gotFrame = 0;
  35. + bool gotFrame;
  36. do
  37. {
  38. int count = 0;
  39. - gotFrame = 0;
  40. + gotFrame = false;
  41. while (!gotFrame && count < 20)
  42. {
  43. From 96c22aa66719846854895afcb72962862d5a4ffd Mon Sep 17 00:00:00 2001
  44. From: Zane van Iperen <zane@zanevaniperen.com>
  45. Date: Mon, 15 Mar 2021 20:39:32 +1000
  46. Subject: [PATCH 3/9] lib/moviedecoder: remove SilenceLogLevel
  47. Was unused.
  48. ---
  49. libffmpegthumbnailer/moviedecoder.cpp | 5 -----
  50. 1 file changed, 5 deletions(-)
  51. diff --git a/libffmpegthumbnailer/moviedecoder.cpp b/libffmpegthumbnailer/moviedecoder.cpp
  52. index 79c950b..21df096 100644
  53. --- a/libffmpegthumbnailer/moviedecoder.cpp
  54. +++ b/libffmpegthumbnailer/moviedecoder.cpp
  55. @@ -41,11 +41,6 @@ using namespace std;
  56. namespace ffmpegthumbnailer
  57. {
  58. -struct SilenceLogLevel
  59. -{
  60. - SilenceLogLevel() { av_log_set_level(AV_LOG_QUIET); }
  61. -};
  62. -
  63. MovieDecoder::MovieDecoder(AVFormatContext* pavContext)
  64. : m_VideoStream(-1)
  65. , m_pFormatContext(pavContext)
  66. From 664680f4bfeb89923f485eba270f9e49a8d02bfc Mon Sep 17 00:00:00 2001
  67. From: Zane van Iperen <zane@zanevaniperen.com>
  68. Date: Mon, 15 Mar 2021 17:25:40 +1000
  69. Subject: [PATCH 4/9] lib/moviedecoder: remove registration calls
  70. They're not needed anymore.
  71. ---
  72. libffmpegthumbnailer/moviedecoder.cpp | 4 ----
  73. 1 file changed, 4 deletions(-)
  74. diff --git a/libffmpegthumbnailer/moviedecoder.cpp b/libffmpegthumbnailer/moviedecoder.cpp
  75. index 21df096..ac3e5b9 100644
  76. --- a/libffmpegthumbnailer/moviedecoder.cpp
  77. +++ b/libffmpegthumbnailer/moviedecoder.cpp
  78. @@ -65,8 +65,6 @@ MovieDecoder::~MovieDecoder()
  79. void MovieDecoder::initialize(const string& filename, bool preferEmbeddedMetadata)
  80. {
  81. - av_register_all();
  82. - avcodec_register_all();
  83. avformat_network_init();
  84. string inputFile = filename == "-" ? "pipe:" : filename;
  85. @@ -386,8 +384,6 @@ void MovieDecoder::initializeFilterGraph(const AVRational& timeBase, const std::
  86. auto del = [] (AVBufferSinkParams* p) { av_freep(p); };
  87. std::unique_ptr<AVBufferSinkParams, decltype(del)> buffersinkParams(av_buffersink_params_alloc(), del);
  88. - avfilter_register_all();
  89. -
  90. m_pFilterGraph = avfilter_graph_alloc();
  91. assert(m_pFilterGraph);
  92. From 1ae42e664e1f3c915d186ae00aa2c8018b998708 Mon Sep 17 00:00:00 2001
  93. From: Zane van Iperen <zane@zanevaniperen.com>
  94. Date: Mon, 15 Mar 2021 17:30:21 +1000
  95. Subject: [PATCH 5/9] lib/moviedecoder: remove use of AVBufferSinkParams
  96. ---
  97. libffmpegthumbnailer/moviedecoder.cpp | 9 +--------
  98. 1 file changed, 1 insertion(+), 8 deletions(-)
  99. diff --git a/libffmpegthumbnailer/moviedecoder.cpp b/libffmpegthumbnailer/moviedecoder.cpp
  100. index ac3e5b9..dece668 100644
  101. --- a/libffmpegthumbnailer/moviedecoder.cpp
  102. +++ b/libffmpegthumbnailer/moviedecoder.cpp
  103. @@ -379,11 +379,6 @@ std::string MovieDecoder::createScaleString(const std::string& sizeString, bool
  104. void MovieDecoder::initializeFilterGraph(const AVRational& timeBase, const std::string& size, bool maintainAspectRatio)
  105. {
  106. - static const AVPixelFormat pixelFormats[] = { AV_PIX_FMT_RGB24, AV_PIX_FMT_NONE };
  107. -
  108. - auto del = [] (AVBufferSinkParams* p) { av_freep(p); };
  109. - std::unique_ptr<AVBufferSinkParams, decltype(del)> buffersinkParams(av_buffersink_params_alloc(), del);
  110. -
  111. m_pFilterGraph = avfilter_graph_alloc();
  112. assert(m_pFilterGraph);
  113. @@ -395,10 +390,8 @@ void MovieDecoder::initializeFilterGraph(const AVRational& timeBase, const std::
  114. checkRc(avfilter_graph_create_filter(&m_pFilterSource, avfilter_get_by_name("buffer"), "thumb_buffer", ss.str().c_str(), nullptr, m_pFilterGraph),
  115. "Failed to create filter source");
  116. - buffersinkParams->pixel_fmts = pixelFormats;
  117. - checkRc(avfilter_graph_create_filter(&m_pFilterSink, avfilter_get_by_name("buffersink"), "thumb_buffersink", nullptr, buffersinkParams.get(), m_pFilterGraph),
  118. + checkRc(avfilter_graph_create_filter(&m_pFilterSink, avfilter_get_by_name("buffersink"), "thumb_buffersink", nullptr, nullptr, m_pFilterGraph),
  119. "Failed to create filter sink");
  120. - buffersinkParams.release();
  121. AVFilterContext* yadifFilter = nullptr;
  122. if (m_pFrame->interlaced_frame != 0)
  123. From 19675349662a4ea4455d7d13b01cca28ab585762 Mon Sep 17 00:00:00 2001
  124. From: Zane van Iperen <zane@zanevaniperen.com>
  125. Date: Mon, 15 Mar 2021 17:39:58 +1000
  126. Subject: [PATCH 6/9] lib/moviedecoder: use m_pVideoCodecContext instead of
  127. AVStream::codec
  128. ---
  129. libffmpegthumbnailer/moviedecoder.cpp | 2 +-
  130. 1 file changed, 1 insertion(+), 1 deletion(-)
  131. diff --git a/libffmpegthumbnailer/moviedecoder.cpp b/libffmpegthumbnailer/moviedecoder.cpp
  132. index dece668..0b7a280 100644
  133. --- a/libffmpegthumbnailer/moviedecoder.cpp
  134. +++ b/libffmpegthumbnailer/moviedecoder.cpp
  135. @@ -484,7 +484,7 @@ void MovieDecoder::seek(int timeInSeconds)
  136. }
  137. checkRc(av_seek_frame(m_pFormatContext, -1, timestamp, 0), "Seeking in video failed");
  138. - avcodec_flush_buffers(m_pFormatContext->streams[m_VideoStream]->codec);
  139. + avcodec_flush_buffers(m_pVideoCodecContext);
  140. int keyFrameAttempts = 0;
  141. bool gotFrame;
  142. From 4f74f83a009fa2b3f3d546adb24d4f1406910007 Mon Sep 17 00:00:00 2001
  143. From: Zane van Iperen <zane@zanevaniperen.com>
  144. Date: Mon, 15 Mar 2021 17:49:03 +1000
  145. Subject: [PATCH 7/9] lib/moviedecoder: codec -> codecpar
  146. ---
  147. libffmpegthumbnailer/moviedecoder.cpp | 6 +++---
  148. 1 file changed, 3 insertions(+), 3 deletions(-)
  149. diff --git a/libffmpegthumbnailer/moviedecoder.cpp b/libffmpegthumbnailer/moviedecoder.cpp
  150. index 0b7a280..e58904e 100644
  151. --- a/libffmpegthumbnailer/moviedecoder.cpp
  152. +++ b/libffmpegthumbnailer/moviedecoder.cpp
  153. @@ -145,10 +145,10 @@ int32_t MovieDecoder::findPreferedVideoStream(bool preferEmbeddedMetadata)
  154. for (unsigned int i = 0; i < m_pFormatContext->nb_streams; ++i)
  155. {
  156. AVStream *stream = m_pFormatContext->streams[i];
  157. - auto ctx = m_pFormatContext->streams[i]->codec;
  158. - if (ctx->codec_type == AVMEDIA_TYPE_VIDEO)
  159. + auto par = m_pFormatContext->streams[i]->codecpar;
  160. + if (par->codec_type == AVMEDIA_TYPE_VIDEO)
  161. {
  162. - if (!preferEmbeddedMetadata || !isStillImageCodec(ctx->codec_id))
  163. + if (!preferEmbeddedMetadata || !isStillImageCodec(par->codec_id))
  164. {
  165. videoStreams.push_back(i);
  166. continue;
  167. From 3ffdd65cbda6ef21d36c96013db1b0f4dc9fc57b Mon Sep 17 00:00:00 2001
  168. From: Zane van Iperen <zane@zanevaniperen.com>
  169. Date: Mon, 15 Mar 2021 17:52:01 +1000
  170. Subject: [PATCH 8/9] lib/movedecoder: don't rely on avformat to allocate a
  171. context
  172. ---
  173. libffmpegthumbnailer/moviedecoder.cpp | 20 ++++++++++++++++----
  174. 1 file changed, 16 insertions(+), 4 deletions(-)
  175. diff --git a/libffmpegthumbnailer/moviedecoder.cpp b/libffmpegthumbnailer/moviedecoder.cpp
  176. index e58904e..da5f32a 100644
  177. --- a/libffmpegthumbnailer/moviedecoder.cpp
  178. +++ b/libffmpegthumbnailer/moviedecoder.cpp
  179. @@ -90,8 +90,7 @@ void MovieDecoder::destroy()
  180. {
  181. if (m_pVideoCodecContext)
  182. {
  183. - avcodec_close(m_pVideoCodecContext);
  184. - m_pVideoCodecContext = nullptr;
  185. + avcodec_free_context(&m_pVideoCodecContext);
  186. }
  187. if ((!m_FormatContextWasGiven) && m_pFormatContext)
  188. @@ -196,8 +195,7 @@ void MovieDecoder::initializeVideo(bool preferEmbeddedMetadata)
  189. }
  190. m_pVideoStream = m_pFormatContext->streams[m_VideoStream];
  191. - m_pVideoCodecContext = m_pVideoStream->codec;
  192. - m_pVideoCodec = avcodec_find_decoder(m_pVideoCodecContext->codec_id);
  193. + m_pVideoCodec = avcodec_find_decoder(m_pVideoStream->codecpar->codec_id);
  194. if (m_pVideoCodec == nullptr)
  195. {
  196. @@ -207,6 +205,20 @@ void MovieDecoder::initializeVideo(bool preferEmbeddedMetadata)
  197. throw logic_error("Video Codec not found");
  198. }
  199. + m_pVideoCodecContext = avcodec_alloc_context3(m_pVideoCodec);
  200. +
  201. + if (m_pVideoCodecContext == nullptr)
  202. + {
  203. + destroy();
  204. + throw logic_error("Could not allocate video codec context");
  205. + }
  206. +
  207. + if (avcodec_parameters_to_context(m_pVideoCodecContext, m_pVideoStream->codecpar) < 0)
  208. + {
  209. + destroy();
  210. + throw logic_error("Could not configure video codec context");
  211. + }
  212. +
  213. m_pVideoCodecContext->workaround_bugs = 1;
  214. if (avcodec_open2(m_pVideoCodecContext, m_pVideoCodec, nullptr) < 0)
  215. From f9273852c8e3d7af77d6c8929b1ac6c8a26eca50 Mon Sep 17 00:00:00 2001
  216. From: Zane van Iperen <zane@zanevaniperen.com>
  217. Date: Mon, 15 Mar 2021 20:57:45 +1000
  218. Subject: [PATCH 9/9] lib/moviedecoder: replace avcodec_decode_video2() usage
  219. ---
  220. libffmpegthumbnailer/moviedecoder.cpp | 31 +++++++++++++++++++++------
  221. 1 file changed, 24 insertions(+), 7 deletions(-)
  222. diff --git a/libffmpegthumbnailer/moviedecoder.cpp b/libffmpegthumbnailer/moviedecoder.cpp
  223. index da5f32a..f32577a 100644
  224. --- a/libffmpegthumbnailer/moviedecoder.cpp
  225. +++ b/libffmpegthumbnailer/moviedecoder.cpp
  226. @@ -548,17 +548,33 @@ bool MovieDecoder::decodeVideoPacket()
  227. return false;
  228. }
  229. - av_frame_unref(m_pFrame);
  230. -
  231. - int frameFinished;
  232. + int rc = avcodec_send_packet(m_pVideoCodecContext, m_pPacket);
  233. + if(rc == AVERROR(EAGAIN))
  234. + {
  235. + rc = 0;
  236. + }
  237. - int bytesDecoded = avcodec_decode_video2(m_pVideoCodecContext, m_pFrame, &frameFinished, m_pPacket);
  238. - if (bytesDecoded < 0)
  239. + if(rc == AVERROR_EOF)
  240. + {
  241. + return false;
  242. + }
  243. + else if(rc < 0)
  244. {
  245. - throw logic_error("Failed to decode video frame: bytesDecoded < 0");
  246. + throw logic_error("Failed to decode video frame: avcodec_send_packet() < 0");
  247. }
  248. - return frameFinished > 0;
  249. + rc = avcodec_receive_frame(m_pVideoCodecContext, m_pFrame);
  250. + switch(rc)
  251. + {
  252. + case 0:
  253. + return true;
  254. +
  255. + case AVERROR(EAGAIN):
  256. + return false;
  257. +
  258. + default:
  259. + throw logic_error("Failed to decode video frame: avcodec_receive_frame() < 0");
  260. + }
  261. }
  262. bool MovieDecoder::getVideoPacket()
  263. @@ -574,6 +590,7 @@ bool MovieDecoder::getVideoPacket()
  264. m_pPacket = new AVPacket();
  265. +
  266. while (framesAvailable && !frameDecoded)
  267. {
  268. framesAvailable = av_read_frame(m_pFormatContext, m_pPacket) >= 0;