ffmpeg3.patch 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. diff -ur blender-2.76/CMakeLists.txt blender-2.76.ffmpeg/CMakeLists.txt
  2. --- blender-2.76/CMakeLists.txt 2015-10-12 00:58:22.000000000 +0200
  3. +++ blender-2.76.ffmpeg/CMakeLists.txt 2016-04-16 15:31:11.524037254 +0200
  4. @@ -982,7 +982,7 @@
  5. if(WITH_CODEC_FFMPEG)
  6. set(FFMPEG /usr CACHE PATH "FFMPEG Directory")
  7. - set(FFMPEG_LIBRARIES avformat avcodec avutil avdevice swscale CACHE STRING "FFMPEG Libraries")
  8. + set(FFMPEG_LIBRARIES avformat avcodec avutil avdevice swscale avfilter CACHE STRING "FFMPEG Libraries")
  9. mark_as_advanced(FFMPEG)
  10. diff -ur blender-2.76/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp blender-2.76.ffmpeg/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
  11. --- blender-2.76/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp 2015-10-07 02:09:33.000000000 +0200
  12. +++ blender-2.76.ffmpeg/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp 2016-04-16 15:31:11.524037254 +0200
  13. @@ -58,9 +58,9 @@
  14. got_frame = 0;
  15. if(!frame)
  16. - frame = avcodec_alloc_frame();
  17. + frame = av_frame_alloc();
  18. else
  19. - avcodec_get_frame_defaults(frame);
  20. + av_frame_unref(frame);
  21. read_length = avcodec_decode_audio4(m_codecCtx, frame, &got_frame, &packet);
  22. if(read_length < 0)
  23. diff -ur blender-2.76/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp blender-2.76.ffmpeg/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp
  24. --- blender-2.76/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp 2015-10-07 02:09:33.000000000 +0200
  25. +++ blender-2.76.ffmpeg/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp 2016-04-16 15:31:11.524037254 +0200
  26. @@ -202,7 +202,7 @@
  27. m_frame = av_frame_alloc();
  28. if (!m_frame)
  29. AUD_THROW(AUD_ERROR_FFMPEG, codec_error);
  30. - avcodec_get_frame_defaults(m_frame);
  31. + av_frame_unref(m_frame);
  32. m_frame->linesize[0] = m_input_size * samplesize;
  33. m_frame->format = m_codecCtx->sample_fmt;
  34. m_frame->nb_samples = m_input_size;
  35. diff -ur blender-2.76/source/blender/blenkernel/intern/writeffmpeg.c blender-2.76.ffmpeg/source/blender/blenkernel/intern/writeffmpeg.c
  36. --- blender-2.76/source/blender/blenkernel/intern/writeffmpeg.c 2015-10-12 00:58:22.000000000 +0200
  37. +++ blender-2.76.ffmpeg/source/blender/blenkernel/intern/writeffmpeg.c 2016-04-16 15:31:11.527370628 +0200
  38. @@ -138,8 +138,8 @@
  39. context->audio_time += (double) context->audio_input_samples / (double) c->sample_rate;
  40. #ifdef FFMPEG_HAVE_ENCODE_AUDIO2
  41. - frame = avcodec_alloc_frame();
  42. - avcodec_get_frame_defaults(frame);
  43. + frame = av_frame_alloc();
  44. + av_frame_unref(frame);
  45. frame->pts = context->audio_time / av_q2d(c->time_base);
  46. frame->nb_samples = context->audio_input_samples;
  47. frame->format = c->sample_fmt;
  48. @@ -172,7 +172,7 @@
  49. }
  50. if (!got_output) {
  51. - avcodec_free_frame(&frame);
  52. + av_frame_free(&frame);
  53. return 0;
  54. }
  55. #else
  56. @@ -202,7 +202,7 @@
  57. if (av_interleaved_write_frame(context->outfile, &pkt) != 0) {
  58. fprintf(stderr, "Error writing audio packet!\n");
  59. if (frame)
  60. - avcodec_free_frame(&frame);
  61. + av_frame_free(&frame);
  62. return -1;
  63. }
  64. @@ -210,7 +210,7 @@
  65. }
  66. if (frame)
  67. - avcodec_free_frame(&frame);
  68. + av_frame_free(&frame);
  69. return 0;
  70. }
  71. @@ -224,7 +224,7 @@
  72. int size;
  73. /* allocate space for the struct */
  74. - f = avcodec_alloc_frame();
  75. + f = av_frame_alloc();
  76. if (!f) return NULL;
  77. size = avpicture_get_size(pix_fmt, width, height);
  78. /* allocate the actual picture buffer */
  79. @@ -363,8 +363,8 @@
  80. int height = c->height;
  81. AVFrame *rgb_frame;
  82. - if (c->pix_fmt != PIX_FMT_BGR32) {
  83. - rgb_frame = alloc_picture(PIX_FMT_BGR32, width, height);
  84. + if (c->pix_fmt != AV_PIX_FMT_BGR32) {
  85. + rgb_frame = alloc_picture(AV_PIX_FMT_BGR32, width, height);
  86. if (!rgb_frame) {
  87. BKE_report(reports, RPT_ERROR, "Could not allocate temporary frame");
  88. return NULL;
  89. @@ -414,14 +414,14 @@
  90. }
  91. }
  92. - if (c->pix_fmt != PIX_FMT_BGR32) {
  93. + if (c->pix_fmt != AV_PIX_FMT_BGR32) {
  94. sws_scale(context->img_convert_ctx, (const uint8_t *const *) rgb_frame->data,
  95. rgb_frame->linesize, 0, c->height,
  96. context->current_frame->data, context->current_frame->linesize);
  97. delete_picture(rgb_frame);
  98. }
  99. - context->current_frame->format = PIX_FMT_BGR32;
  100. + context->current_frame->format = AV_PIX_FMT_BGR32;
  101. context->current_frame->width = width;
  102. context->current_frame->height = height;
  103. @@ -586,12 +586,12 @@
  104. }
  105. else {
  106. /* makes HuffYUV happy ... */
  107. - c->pix_fmt = PIX_FMT_YUV422P;
  108. + c->pix_fmt = AV_PIX_FMT_YUV422P;
  109. }
  110. if (context->ffmpeg_type == FFMPEG_XVID) {
  111. /* arghhhh ... */
  112. - c->pix_fmt = PIX_FMT_YUV420P;
  113. + c->pix_fmt = AV_PIX_FMT_YUV420P;
  114. c->codec_tag = (('D' << 24) + ('I' << 16) + ('V' << 8) + 'X');
  115. }
  116. @@ -604,26 +604,26 @@
  117. /* Keep lossless encodes in the RGB domain. */
  118. if (codec_id == AV_CODEC_ID_HUFFYUV) {
  119. if (rd->im_format.planes == R_IMF_PLANES_RGBA) {
  120. - c->pix_fmt = PIX_FMT_BGRA;
  121. + c->pix_fmt = AV_PIX_FMT_BGRA;
  122. }
  123. else {
  124. - c->pix_fmt = PIX_FMT_RGB32;
  125. + c->pix_fmt = AV_PIX_FMT_RGB32;
  126. }
  127. }
  128. if (codec_id == AV_CODEC_ID_FFV1) {
  129. - c->pix_fmt = PIX_FMT_RGB32;
  130. + c->pix_fmt = AV_PIX_FMT_RGB32;
  131. }
  132. if (codec_id == AV_CODEC_ID_QTRLE) {
  133. if (rd->im_format.planes == R_IMF_PLANES_RGBA) {
  134. - c->pix_fmt = PIX_FMT_ARGB;
  135. + c->pix_fmt = AV_PIX_FMT_ARGB;
  136. }
  137. }
  138. if (codec_id == AV_CODEC_ID_PNG) {
  139. if (rd->im_format.planes == R_IMF_PLANES_RGBA) {
  140. - c->pix_fmt = PIX_FMT_RGBA;
  141. + c->pix_fmt = AV_PIX_FMT_RGBA;
  142. }
  143. }
  144. @@ -661,7 +661,7 @@
  145. context->current_frame = alloc_picture(c->pix_fmt, c->width, c->height);
  146. - context->img_convert_ctx = sws_getContext(c->width, c->height, PIX_FMT_BGR32, c->width, c->height, c->pix_fmt, SWS_BICUBIC,
  147. + context->img_convert_ctx = sws_getContext(c->width, c->height, AV_PIX_FMT_BGR32, c->width, c->height, c->pix_fmt, SWS_BICUBIC,
  148. NULL, NULL, NULL);
  149. return st;
  150. }
  151. diff -ur blender-2.76/source/blender/imbuf/intern/anim_movie.c blender-2.76.ffmpeg/source/blender/imbuf/intern/anim_movie.c
  152. --- blender-2.76/source/blender/imbuf/intern/anim_movie.c 2015-10-07 02:09:33.000000000 +0200
  153. +++ blender-2.76.ffmpeg/source/blender/imbuf/intern/anim_movie.c 2016-04-16 15:31:11.527370628 +0200
  154. @@ -474,6 +474,10 @@
  155. const int *inv_table;
  156. #endif
  157. + anim->last_width = -1;
  158. + anim->last_height = -1;
  159. + anim->last_pixfmt = AV_PIX_FMT_NONE;
  160. +
  161. if (anim == NULL) return(-1);
  162. streamcount = anim->streamindex;
  163. @@ -562,21 +566,21 @@
  164. anim->next_pts = -1;
  165. anim->next_packet.stream_index = -1;
  166. - anim->pFrame = avcodec_alloc_frame();
  167. + anim->pFrame = av_frame_alloc();
  168. anim->pFrameComplete = false;
  169. - anim->pFrameDeinterlaced = avcodec_alloc_frame();
  170. - anim->pFrameRGB = avcodec_alloc_frame();
  171. + anim->pFrameDeinterlaced = av_frame_alloc();
  172. + anim->pFrameRGB = av_frame_alloc();
  173. - if (avpicture_get_size(PIX_FMT_RGBA, anim->x, anim->y) !=
  174. + if (avpicture_get_size(AV_PIX_FMT_RGBA, anim->x, anim->y) !=
  175. anim->x * anim->y * 4)
  176. {
  177. fprintf(stderr,
  178. "ffmpeg has changed alloc scheme ... ARGHHH!\n");
  179. avcodec_close(anim->pCodecCtx);
  180. avformat_close_input(&anim->pFormatCtx);
  181. - av_free(anim->pFrameRGB);
  182. - av_free(anim->pFrameDeinterlaced);
  183. - av_free(anim->pFrame);
  184. + av_frame_free(&anim->pFrameRGB);
  185. + av_frame_free(&anim->pFrameDeinterlaced);
  186. + av_frame_free(&anim->pFrame);
  187. anim->pCodecCtx = NULL;
  188. return -1;
  189. }
  190. @@ -606,7 +610,7 @@
  191. anim->pCodecCtx->pix_fmt,
  192. anim->x,
  193. anim->y,
  194. - PIX_FMT_RGBA,
  195. + AV_PIX_FMT_RGBA,
  196. SWS_FAST_BILINEAR | SWS_PRINT_INFO | SWS_FULL_CHR_H_INT,
  197. NULL, NULL, NULL);
  198. @@ -615,9 +619,9 @@
  199. "Can't transform color space??? Bailing out...\n");
  200. avcodec_close(anim->pCodecCtx);
  201. avformat_close_input(&anim->pFormatCtx);
  202. - av_free(anim->pFrameRGB);
  203. - av_free(anim->pFrameDeinterlaced);
  204. - av_free(anim->pFrame);
  205. + av_frame_free(&anim->pFrameRGB);
  206. + av_frame_free(&anim->pFrameDeinterlaced);
  207. + av_frame_free(&anim->pFrame);
  208. anim->pCodecCtx = NULL;
  209. return -1;
  210. }
  211. @@ -644,6 +648,74 @@
  212. return (0);
  213. }
  214. +static void delete_filter_graph(struct anim *anim) {
  215. + if (anim->filter_graph) {
  216. + av_frame_free(&anim->filter_frame);
  217. + avfilter_graph_free(&anim->filter_graph);
  218. + }
  219. +}
  220. +
  221. +static int init_filter_graph(struct anim *anim, enum AVPixelFormat pixfmt, int width, int height) {
  222. + AVFilterInOut *inputs = NULL, *outputs = NULL;
  223. + char args[512];
  224. + int res;
  225. +
  226. + delete_filter_graph(anim);
  227. + anim->filter_graph = avfilter_graph_alloc();
  228. + snprintf(args, sizeof(args),
  229. + "buffer=video_size=%dx%d:pix_fmt=%d:time_base=1/1:pixel_aspect=0/1[in];"
  230. + "[in]yadif[out];"
  231. + "[out]buffersink",
  232. + width, height, pixfmt);
  233. + res = avfilter_graph_parse2(anim->filter_graph, args, &inputs, &outputs);
  234. + if (res < 0)
  235. + return res;
  236. + if(inputs || outputs)
  237. + return -1;
  238. + res = avfilter_graph_config(anim->filter_graph, NULL);
  239. + if (res < 0)
  240. + return res;
  241. +
  242. + anim->buffersrc_ctx = avfilter_graph_get_filter(anim->filter_graph, "Parsed_buffer_0");
  243. + anim->buffersink_ctx = avfilter_graph_get_filter(anim->filter_graph, "Parsed_buffersink_2");
  244. + if (!anim->buffersrc_ctx || !anim->buffersink_ctx)
  245. + return -1;
  246. + anim->filter_frame = av_frame_alloc();
  247. + anim->last_width = width;
  248. + anim->last_height = height;
  249. + anim->last_pixfmt = pixfmt;
  250. +
  251. + return 0;
  252. +}
  253. +
  254. +static int process_filter_graph(struct anim *anim, AVPicture *dst, const AVPicture *src,
  255. + enum AVPixelFormat pixfmt, int width, int height) {
  256. + int res;
  257. +
  258. + if (!anim->filter_graph || width != anim->last_width ||
  259. + height != anim->last_height || pixfmt != anim->last_pixfmt) {
  260. + res = init_filter_graph(anim, pixfmt, width, height);
  261. + if (res < 0)
  262. + return res;
  263. + }
  264. +
  265. + memcpy(anim->filter_frame->data, src->data, sizeof(src->data));
  266. + memcpy(anim->filter_frame->linesize, src->linesize, sizeof(src->linesize));
  267. + anim->filter_frame->width = width;
  268. + anim->filter_frame->height = height;
  269. + anim->filter_frame->format = pixfmt;
  270. + res = av_buffersrc_add_frame(anim->buffersrc_ctx, anim->filter_frame);
  271. + if (res < 0)
  272. + return res;
  273. + res = av_buffersink_get_frame(anim->buffersink_ctx, anim->filter_frame);
  274. + if (res < 0)
  275. + return res;
  276. + av_picture_copy(dst, (const AVPicture *) anim->filter_frame, pixfmt, width, height);
  277. + av_frame_unref(anim->filter_frame);
  278. +
  279. + return 0;
  280. +}
  281. +
  282. /* postprocess the image in anim->pFrame and do color conversion
  283. * and deinterlacing stuff.
  284. *
  285. @@ -677,7 +749,8 @@
  286. if (anim->ib_flags & IB_animdeinterlace) {
  287. - if (avpicture_deinterlace(
  288. + if (process_filter_graph(
  289. + anim,
  290. (AVPicture *)
  291. anim->pFrameDeinterlaced,
  292. (const AVPicture *)
  293. @@ -695,7 +768,7 @@
  294. avpicture_fill((AVPicture *) anim->pFrameRGB,
  295. (unsigned char *) ibuf->rect,
  296. - PIX_FMT_RGBA, anim->x, anim->y);
  297. + AV_PIX_FMT_RGBA, anim->x, anim->y);
  298. if (ENDIAN_ORDER == B_ENDIAN) {
  299. int *dstStride = anim->pFrameRGB->linesize;
  300. @@ -1138,16 +1211,18 @@
  301. {
  302. if (anim == NULL) return;
  303. + delete_filter_graph(anim);
  304. +
  305. if (anim->pCodecCtx) {
  306. avcodec_close(anim->pCodecCtx);
  307. avformat_close_input(&anim->pFormatCtx);
  308. - av_free(anim->pFrameRGB);
  309. - av_free(anim->pFrame);
  310. + av_frame_free(&anim->pFrameRGB);
  311. + av_frame_free(&anim->pFrame);
  312. if (anim->ib_flags & IB_animdeinterlace) {
  313. MEM_freeN(anim->pFrameDeinterlaced->data[0]);
  314. }
  315. - av_free(anim->pFrameDeinterlaced);
  316. + av_frame_free(&anim->pFrameDeinterlaced);
  317. sws_freeContext(anim->img_convert_ctx);
  318. IMB_freeImBuf(anim->last_frame);
  319. if (anim->next_packet.stream_index != -1) {
  320. diff -ur blender-2.76/source/blender/imbuf/intern/IMB_anim.h blender-2.76.ffmpeg/source/blender/imbuf/intern/IMB_anim.h
  321. --- blender-2.76/source/blender/imbuf/intern/IMB_anim.h 2015-10-07 02:09:33.000000000 +0200
  322. +++ blender-2.76.ffmpeg/source/blender/imbuf/intern/IMB_anim.h 2016-04-16 15:31:11.527370628 +0200
  323. @@ -76,6 +76,9 @@
  324. # include <libavformat/avformat.h>
  325. # include <libavcodec/avcodec.h>
  326. # include <libswscale/swscale.h>
  327. +# include <libavfilter/avfilter.h>
  328. +# include <libavfilter/buffersrc.h>
  329. +# include <libavfilter/buffersink.h>
  330. #endif
  331. #ifdef WITH_REDCODE
  332. @@ -175,6 +178,14 @@
  333. int64_t last_pts;
  334. int64_t next_pts;
  335. AVPacket next_packet;
  336. +
  337. + AVFilterContext *buffersink_ctx;
  338. + AVFilterContext *buffersrc_ctx;
  339. + AVFilterGraph *filter_graph;
  340. + AVFrame *filter_frame;
  341. + int last_width;
  342. + int last_height;
  343. + enum AVPixelFormat last_pixfmt;
  344. #endif
  345. #ifdef WITH_REDCODE
  346. diff -ur blender-2.76/source/blender/imbuf/intern/indexer.c blender-2.76.ffmpeg/source/blender/imbuf/intern/indexer.c
  347. --- blender-2.76/source/blender/imbuf/intern/indexer.c 2015-10-07 02:09:33.000000000 +0200
  348. +++ blender-2.76.ffmpeg/source/blender/imbuf/intern/indexer.c 2016-04-16 15:31:11.527370628 +0200
  349. @@ -519,7 +519,7 @@
  350. rv->c->pix_fmt = rv->codec->pix_fmts[0];
  351. }
  352. else {
  353. - rv->c->pix_fmt = PIX_FMT_YUVJ420P;
  354. + rv->c->pix_fmt = AV_PIX_FMT_YUVJ420P;
  355. }
  356. rv->c->sample_aspect_ratio =
  357. @@ -554,7 +554,7 @@
  358. if (st->codec->width != width || st->codec->height != height ||
  359. st->codec->pix_fmt != rv->c->pix_fmt)
  360. {
  361. - rv->frame = avcodec_alloc_frame();
  362. + rv->frame = av_frame_alloc();
  363. avpicture_fill((AVPicture *) rv->frame,
  364. MEM_mallocN(avpicture_get_size(
  365. rv->c->pix_fmt,
  366. @@ -675,7 +675,7 @@
  367. sws_freeContext(ctx->sws_ctx);
  368. MEM_freeN(ctx->frame->data[0]);
  369. - av_free(ctx->frame);
  370. + av_frame_free(&ctx->frame);
  371. }
  372. get_proxy_filename(ctx->anim, ctx->proxy_size,
  373. @@ -905,7 +905,7 @@
  374. memset(&next_packet, 0, sizeof(AVPacket));
  375. - in_frame = avcodec_alloc_frame();
  376. + in_frame = av_frame_alloc();
  377. stream_size = avio_size(context->iFormatCtx->pb);
  378. @@ -973,7 +973,7 @@
  379. } while (frame_finished);
  380. }
  381. - av_free(in_frame);
  382. + av_frame_free(&in_frame);
  383. return 1;
  384. }
  385. diff -ur blender-2.76/source/gameengine/VideoTexture/VideoFFmpeg.cpp blender-2.76.ffmpeg/source/gameengine/VideoTexture/VideoFFmpeg.cpp
  386. --- blender-2.76/source/gameengine/VideoTexture/VideoFFmpeg.cpp 2015-10-12 00:58:22.000000000 +0200
  387. +++ blender-2.76.ffmpeg/source/gameengine/VideoTexture/VideoFFmpeg.cpp 2016-04-16 15:31:11.527370628 +0200
  388. @@ -79,11 +79,16 @@
  389. BLI_listbase_clear(&m_frameCacheBase);
  390. BLI_listbase_clear(&m_packetCacheFree);
  391. BLI_listbase_clear(&m_packetCacheBase);
  392. + last_width = -1;
  393. + last_height = -1;
  394. + last_pixfmt = AV_PIX_FMT_NONE;
  395. +
  396. }
  397. // destructor
  398. VideoFFmpeg::~VideoFFmpeg ()
  399. {
  400. + delete_filter_graph(this);
  401. }
  402. void VideoFFmpeg::refresh(void)
  403. @@ -140,23 +145,23 @@
  404. AVFrame *VideoFFmpeg::allocFrameRGB()
  405. {
  406. AVFrame *frame;
  407. - frame = avcodec_alloc_frame();
  408. + frame = av_frame_alloc();
  409. if (m_format == RGBA32)
  410. {
  411. avpicture_fill((AVPicture*)frame,
  412. (uint8_t*)MEM_callocN(avpicture_get_size(
  413. - PIX_FMT_RGBA,
  414. + AV_PIX_FMT_RGBA,
  415. m_codecCtx->width, m_codecCtx->height),
  416. "ffmpeg rgba"),
  417. - PIX_FMT_RGBA, m_codecCtx->width, m_codecCtx->height);
  418. + AV_PIX_FMT_RGBA, m_codecCtx->width, m_codecCtx->height);
  419. } else
  420. {
  421. avpicture_fill((AVPicture*)frame,
  422. (uint8_t*)MEM_callocN(avpicture_get_size(
  423. - PIX_FMT_RGB24,
  424. + AV_PIX_FMT_RGB24,
  425. m_codecCtx->width, m_codecCtx->height),
  426. "ffmpeg rgb"),
  427. - PIX_FMT_RGB24, m_codecCtx->width, m_codecCtx->height);
  428. + AV_PIX_FMT_RGB24, m_codecCtx->width, m_codecCtx->height);
  429. }
  430. return frame;
  431. }
  432. @@ -236,8 +241,8 @@
  433. m_codecCtx = codecCtx;
  434. m_formatCtx = formatCtx;
  435. m_videoStream = videoStream;
  436. - m_frame = avcodec_alloc_frame();
  437. - m_frameDeinterlaced = avcodec_alloc_frame();
  438. + m_frame = av_frame_alloc();
  439. + m_frameDeinterlaced = av_frame_alloc();
  440. // allocate buffer if deinterlacing is required
  441. avpicture_fill((AVPicture*)m_frameDeinterlaced,
  442. @@ -248,10 +253,10 @@
  443. m_codecCtx->pix_fmt, m_codecCtx->width, m_codecCtx->height);
  444. // check if the pixel format supports Alpha
  445. - if (m_codecCtx->pix_fmt == PIX_FMT_RGB32 ||
  446. - m_codecCtx->pix_fmt == PIX_FMT_BGR32 ||
  447. - m_codecCtx->pix_fmt == PIX_FMT_RGB32_1 ||
  448. - m_codecCtx->pix_fmt == PIX_FMT_BGR32_1)
  449. + if (m_codecCtx->pix_fmt == AV_PIX_FMT_RGB32 ||
  450. + m_codecCtx->pix_fmt == AV_PIX_FMT_BGR32 ||
  451. + m_codecCtx->pix_fmt == AV_PIX_FMT_RGB32_1 ||
  452. + m_codecCtx->pix_fmt == AV_PIX_FMT_BGR32_1)
  453. {
  454. // allocate buffer to store final decoded frame
  455. m_format = RGBA32;
  456. @@ -262,7 +267,7 @@
  457. m_codecCtx->pix_fmt,
  458. m_codecCtx->width,
  459. m_codecCtx->height,
  460. - PIX_FMT_RGBA,
  461. + AV_PIX_FMT_RGBA,
  462. SWS_FAST_BILINEAR,
  463. NULL, NULL, NULL);
  464. } else
  465. @@ -276,7 +281,7 @@
  466. m_codecCtx->pix_fmt,
  467. m_codecCtx->width,
  468. m_codecCtx->height,
  469. - PIX_FMT_RGB24,
  470. + AV_PIX_FMT_RGB24,
  471. SWS_FAST_BILINEAR,
  472. NULL, NULL, NULL);
  473. }
  474. @@ -293,13 +298,81 @@
  475. av_free(m_frameDeinterlaced);
  476. m_frameDeinterlaced = NULL;
  477. MEM_freeN(m_frameRGB->data[0]);
  478. - av_free(m_frameRGB);
  479. + av_frame_free(&m_frameRGB);
  480. m_frameRGB = NULL;
  481. return -1;
  482. }
  483. return 0;
  484. }
  485. +void VideoFFmpeg::delete_filter_graph(VideoFFmpeg* video) {
  486. + if (video->filter_graph) {
  487. + av_frame_free(&video->filter_frame);
  488. + avfilter_graph_free(&video->filter_graph);
  489. + }
  490. +}
  491. +
  492. +int VideoFFmpeg::init_filter_graph(VideoFFmpeg* video, enum AVPixelFormat pixfmt, int width, int height) {
  493. + AVFilterInOut *inputs = NULL, *outputs = NULL;
  494. + char args[512];
  495. + int res;
  496. +
  497. + delete_filter_graph(video);
  498. + video->filter_graph = avfilter_graph_alloc();
  499. + snprintf(args, sizeof(args),
  500. + "buffer=video_size=%dx%d:pix_fmt=%d:time_base=1/1:pixel_aspect=0/1[in];"
  501. + "[in]yadif[out];"
  502. + "[out]buffersink",
  503. + width, height, pixfmt);
  504. + res = avfilter_graph_parse2(video->filter_graph, args, &inputs, &outputs);
  505. + if (res < 0)
  506. + return res;
  507. + if(inputs || outputs)
  508. + return -1;
  509. + res = avfilter_graph_config(video->filter_graph, NULL);
  510. + if (res < 0)
  511. + return res;
  512. +
  513. + video->buffersrc_ctx = avfilter_graph_get_filter(video->filter_graph, "Parsed_buffer_0");
  514. + video->buffersink_ctx = avfilter_graph_get_filter(video->filter_graph, "Parsed_buffersink_2");
  515. + if (!video->buffersrc_ctx || !video->buffersink_ctx)
  516. + return -1;
  517. + video->filter_frame = av_frame_alloc();
  518. + video->last_width = width;
  519. + video->last_height = height;
  520. + video->last_pixfmt = pixfmt;
  521. +
  522. + return 0;
  523. +}
  524. +
  525. +int VideoFFmpeg::process_filter_graph(VideoFFmpeg* video, AVPicture *dst, const AVPicture *src,
  526. + enum AVPixelFormat pixfmt, int width, int height) {
  527. + int res;
  528. +
  529. + if (!video->filter_graph || width != video->last_width ||
  530. + height != video->last_height || pixfmt != video->last_pixfmt) {
  531. + res = init_filter_graph(video, pixfmt, width, height);
  532. + if (res < 0)
  533. + return res;
  534. + }
  535. +
  536. + memcpy(video->filter_frame->data, src->data, sizeof(src->data));
  537. + memcpy(video->filter_frame->linesize, src->linesize, sizeof(src->linesize));
  538. + video->filter_frame->width = width;
  539. + video->filter_frame->height = height;
  540. + video->filter_frame->format = pixfmt;
  541. + res = av_buffersrc_add_frame(video->buffersrc_ctx, video->filter_frame);
  542. + if (res < 0)
  543. + return res;
  544. + res = av_buffersink_get_frame(video->buffersink_ctx, video->filter_frame);
  545. + if (res < 0)
  546. + return res;
  547. + av_picture_copy(dst, (const AVPicture *) video->filter_frame, pixfmt, width, height);
  548. + av_frame_unref(video->filter_frame);
  549. +
  550. + return 0;
  551. +}
  552. +
  553. /*
  554. * This thread is used to load video frame asynchronously.
  555. * It provides a frame caching service.
  556. @@ -392,7 +465,7 @@
  557. {
  558. if (video->m_deinterlace)
  559. {
  560. - if (avpicture_deinterlace(
  561. + if (process_filter_graph(video,
  562. (AVPicture*) video->m_frameDeinterlaced,
  563. (const AVPicture*) video->m_frame,
  564. video->m_codecCtx->pix_fmt,
  565. @@ -486,14 +559,14 @@
  566. {
  567. BLI_remlink(&m_frameCacheBase, frame);
  568. MEM_freeN(frame->frame->data[0]);
  569. - av_free(frame->frame);
  570. + av_frame_free(&frame->frame);
  571. delete frame;
  572. }
  573. while ((frame = (CacheFrame *)m_frameCacheFree.first) != NULL)
  574. {
  575. BLI_remlink(&m_frameCacheFree, frame);
  576. MEM_freeN(frame->frame->data[0]);
  577. - av_free(frame->frame);
  578. + av_frame_free(&frame->frame);
  579. delete frame;
  580. }
  581. while ((packet = (CachePacket *)m_packetCacheBase.first) != NULL)
  582. @@ -1057,7 +1130,7 @@
  583. if (m_deinterlace)
  584. {
  585. - if (avpicture_deinterlace(
  586. + if (process_filter_graph(this,
  587. (AVPicture*) m_frameDeinterlaced,
  588. (const AVPicture*) m_frame,
  589. m_codecCtx->pix_fmt,
  590. diff -ur blender-2.76/source/gameengine/VideoTexture/VideoFFmpeg.h blender-2.76.ffmpeg/source/gameengine/VideoTexture/VideoFFmpeg.h
  591. --- blender-2.76/source/gameengine/VideoTexture/VideoFFmpeg.h 2015-10-10 10:20:56.000000000 +0200
  592. +++ blender-2.76.ffmpeg/source/gameengine/VideoTexture/VideoFFmpeg.h 2016-04-16 15:31:11.527370628 +0200
  593. @@ -39,6 +39,9 @@
  594. extern "C" {
  595. #include <pthread.h>
  596. #include "ffmpeg_compat.h"
  597. +#include <libavfilter/avfilter.h>
  598. +#include <libavfilter/buffersrc.h>
  599. +#include <libavfilter/buffersink.h>
  600. #include "DNA_listBase.h"
  601. #include "BLI_threads.h"
  602. #include "BLI_blenlib.h"
  603. @@ -207,6 +210,18 @@
  604. AVFrame *allocFrameRGB();
  605. static void *cacheThread(void *);
  606. +
  607. + AVFilterContext *buffersink_ctx;
  608. + AVFilterContext *buffersrc_ctx;
  609. + AVFilterGraph *filter_graph;
  610. + AVFrame *filter_frame;
  611. + int last_width;
  612. + int last_height;
  613. + enum AVPixelFormat last_pixfmt;
  614. +
  615. + static void delete_filter_graph(VideoFFmpeg* video);
  616. + static int init_filter_graph(VideoFFmpeg* video, enum AVPixelFormat pixfmt, int width, int height);
  617. + static int process_filter_graph(VideoFFmpeg* video, AVPicture *dst, const AVPicture *src, enum AVPixelFormat pixfmt, int width, int height);
  618. };
  619. inline VideoFFmpeg *getFFmpeg(PyImage *self)