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
7 set(FFMPEG /usr CACHE PATH "FFMPEG Directory")
8 - set(FFMPEG_LIBRARIES avformat avcodec avutil avdevice swscale CACHE STRING "FFMPEG Libraries")
9 + set(FFMPEG_LIBRARIES avformat avcodec avutil avdevice swscale avfilter CACHE STRING "FFMPEG Libraries")
11 mark_as_advanced(FFMPEG)
13 diff -ur blender-2.76/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp blender-2.76.ffmpeg/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
14 --- blender-2.76/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp 2015-10-07 02:09:33.000000000 +0200
15 +++ blender-2.76.ffmpeg/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp 2016-04-16 15:31:11.524037254 +0200
20 - frame = avcodec_alloc_frame();
21 + frame = av_frame_alloc();
23 - avcodec_get_frame_defaults(frame);
24 + av_frame_unref(frame);
26 read_length = avcodec_decode_audio4(m_codecCtx, frame, &got_frame, &packet);
28 diff -ur blender-2.76/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp blender-2.76.ffmpeg/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp
29 --- blender-2.76/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp 2015-10-07 02:09:33.000000000 +0200
30 +++ blender-2.76.ffmpeg/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp 2016-04-16 15:31:11.524037254 +0200
32 m_frame = av_frame_alloc();
34 AUD_THROW(AUD_ERROR_FFMPEG, codec_error);
35 - avcodec_get_frame_defaults(m_frame);
36 + av_frame_unref(m_frame);
37 m_frame->linesize[0] = m_input_size * samplesize;
38 m_frame->format = m_codecCtx->sample_fmt;
39 m_frame->nb_samples = m_input_size;
40 diff -ur blender-2.76/source/blender/blenkernel/intern/writeffmpeg.c blender-2.76.ffmpeg/source/blender/blenkernel/intern/writeffmpeg.c
41 --- blender-2.76/source/blender/blenkernel/intern/writeffmpeg.c 2015-10-12 00:58:22.000000000 +0200
42 +++ blender-2.76.ffmpeg/source/blender/blenkernel/intern/writeffmpeg.c 2016-04-16 15:31:11.527370628 +0200
44 context->audio_time += (double) context->audio_input_samples / (double) c->sample_rate;
46 #ifdef FFMPEG_HAVE_ENCODE_AUDIO2
47 - frame = avcodec_alloc_frame();
48 - avcodec_get_frame_defaults(frame);
49 + frame = av_frame_alloc();
50 + av_frame_unref(frame);
51 frame->pts = context->audio_time / av_q2d(c->time_base);
52 frame->nb_samples = context->audio_input_samples;
53 frame->format = c->sample_fmt;
58 - avcodec_free_frame(&frame);
59 + av_frame_free(&frame);
64 if (av_interleaved_write_frame(context->outfile, &pkt) != 0) {
65 fprintf(stderr, "Error writing audio packet!\n");
67 - avcodec_free_frame(&frame);
68 + av_frame_free(&frame);
76 - avcodec_free_frame(&frame);
77 + av_frame_free(&frame);
84 /* allocate space for the struct */
85 - f = avcodec_alloc_frame();
86 + f = av_frame_alloc();
88 size = avpicture_get_size(pix_fmt, width, height);
89 /* allocate the actual picture buffer */
91 int height = c->height;
94 - if (c->pix_fmt != PIX_FMT_BGR32) {
95 - rgb_frame = alloc_picture(PIX_FMT_BGR32, width, height);
96 + if (c->pix_fmt != AV_PIX_FMT_BGR32) {
97 + rgb_frame = alloc_picture(AV_PIX_FMT_BGR32, width, height);
99 BKE_report(reports, RPT_ERROR, "Could not allocate temporary frame");
101 @@ -414,14 +414,14 @@
105 - if (c->pix_fmt != PIX_FMT_BGR32) {
106 + if (c->pix_fmt != AV_PIX_FMT_BGR32) {
107 sws_scale(context->img_convert_ctx, (const uint8_t *const *) rgb_frame->data,
108 rgb_frame->linesize, 0, c->height,
109 context->current_frame->data, context->current_frame->linesize);
110 delete_picture(rgb_frame);
113 - context->current_frame->format = PIX_FMT_BGR32;
114 + context->current_frame->format = AV_PIX_FMT_BGR32;
115 context->current_frame->width = width;
116 context->current_frame->height = height;
118 @@ -586,12 +586,12 @@
121 /* makes HuffYUV happy ... */
122 - c->pix_fmt = PIX_FMT_YUV422P;
123 + c->pix_fmt = AV_PIX_FMT_YUV422P;
126 if (context->ffmpeg_type == FFMPEG_XVID) {
128 - c->pix_fmt = PIX_FMT_YUV420P;
129 + c->pix_fmt = AV_PIX_FMT_YUV420P;
130 c->codec_tag = (('D' << 24) + ('I' << 16) + ('V' << 8) + 'X');
133 @@ -604,26 +604,26 @@
134 /* Keep lossless encodes in the RGB domain. */
135 if (codec_id == AV_CODEC_ID_HUFFYUV) {
136 if (rd->im_format.planes == R_IMF_PLANES_RGBA) {
137 - c->pix_fmt = PIX_FMT_BGRA;
138 + c->pix_fmt = AV_PIX_FMT_BGRA;
141 - c->pix_fmt = PIX_FMT_RGB32;
142 + c->pix_fmt = AV_PIX_FMT_RGB32;
146 if (codec_id == AV_CODEC_ID_FFV1) {
147 - c->pix_fmt = PIX_FMT_RGB32;
148 + c->pix_fmt = AV_PIX_FMT_RGB32;
151 if (codec_id == AV_CODEC_ID_QTRLE) {
152 if (rd->im_format.planes == R_IMF_PLANES_RGBA) {
153 - c->pix_fmt = PIX_FMT_ARGB;
154 + c->pix_fmt = AV_PIX_FMT_ARGB;
158 if (codec_id == AV_CODEC_ID_PNG) {
159 if (rd->im_format.planes == R_IMF_PLANES_RGBA) {
160 - c->pix_fmt = PIX_FMT_RGBA;
161 + c->pix_fmt = AV_PIX_FMT_RGBA;
167 context->current_frame = alloc_picture(c->pix_fmt, c->width, c->height);
169 - context->img_convert_ctx = sws_getContext(c->width, c->height, PIX_FMT_BGR32, c->width, c->height, c->pix_fmt, SWS_BICUBIC,
170 + context->img_convert_ctx = sws_getContext(c->width, c->height, AV_PIX_FMT_BGR32, c->width, c->height, c->pix_fmt, SWS_BICUBIC,
174 diff -ur blender-2.76/source/blender/imbuf/intern/anim_movie.c blender-2.76.ffmpeg/source/blender/imbuf/intern/anim_movie.c
175 --- blender-2.76/source/blender/imbuf/intern/anim_movie.c 2015-10-07 02:09:33.000000000 +0200
176 +++ blender-2.76.ffmpeg/source/blender/imbuf/intern/anim_movie.c 2016-04-16 15:31:11.527370628 +0200
178 const int *inv_table;
181 + anim->last_width = -1;
182 + anim->last_height = -1;
183 + anim->last_pixfmt = AV_PIX_FMT_NONE;
185 if (anim == NULL) return(-1);
187 streamcount = anim->streamindex;
188 @@ -562,21 +566,21 @@
190 anim->next_packet.stream_index = -1;
192 - anim->pFrame = avcodec_alloc_frame();
193 + anim->pFrame = av_frame_alloc();
194 anim->pFrameComplete = false;
195 - anim->pFrameDeinterlaced = avcodec_alloc_frame();
196 - anim->pFrameRGB = avcodec_alloc_frame();
197 + anim->pFrameDeinterlaced = av_frame_alloc();
198 + anim->pFrameRGB = av_frame_alloc();
200 - if (avpicture_get_size(PIX_FMT_RGBA, anim->x, anim->y) !=
201 + if (avpicture_get_size(AV_PIX_FMT_RGBA, anim->x, anim->y) !=
202 anim->x * anim->y * 4)
205 "ffmpeg has changed alloc scheme ... ARGHHH!\n");
206 avcodec_close(anim->pCodecCtx);
207 avformat_close_input(&anim->pFormatCtx);
208 - av_free(anim->pFrameRGB);
209 - av_free(anim->pFrameDeinterlaced);
210 - av_free(anim->pFrame);
211 + av_frame_free(&anim->pFrameRGB);
212 + av_frame_free(&anim->pFrameDeinterlaced);
213 + av_frame_free(&anim->pFrame);
214 anim->pCodecCtx = NULL;
218 anim->pCodecCtx->pix_fmt,
223 SWS_FAST_BILINEAR | SWS_PRINT_INFO | SWS_FULL_CHR_H_INT,
227 "Can't transform color space??? Bailing out...\n");
228 avcodec_close(anim->pCodecCtx);
229 avformat_close_input(&anim->pFormatCtx);
230 - av_free(anim->pFrameRGB);
231 - av_free(anim->pFrameDeinterlaced);
232 - av_free(anim->pFrame);
233 + av_frame_free(&anim->pFrameRGB);
234 + av_frame_free(&anim->pFrameDeinterlaced);
235 + av_frame_free(&anim->pFrame);
236 anim->pCodecCtx = NULL;
243 +static void delete_filter_graph(struct anim *anim) {
244 + if (anim->filter_graph) {
245 + av_frame_free(&anim->filter_frame);
246 + avfilter_graph_free(&anim->filter_graph);
250 +static int init_filter_graph(struct anim *anim, enum AVPixelFormat pixfmt, int width, int height) {
251 + AVFilterInOut *inputs = NULL, *outputs = NULL;
255 + delete_filter_graph(anim);
256 + anim->filter_graph = avfilter_graph_alloc();
257 + snprintf(args, sizeof(args),
258 + "buffer=video_size=%dx%d:pix_fmt=%d:time_base=1/1:pixel_aspect=0/1[in];"
261 + width, height, pixfmt);
262 + res = avfilter_graph_parse2(anim->filter_graph, args, &inputs, &outputs);
265 + if(inputs || outputs)
267 + res = avfilter_graph_config(anim->filter_graph, NULL);
271 + anim->buffersrc_ctx = avfilter_graph_get_filter(anim->filter_graph, "Parsed_buffer_0");
272 + anim->buffersink_ctx = avfilter_graph_get_filter(anim->filter_graph, "Parsed_buffersink_2");
273 + if (!anim->buffersrc_ctx || !anim->buffersink_ctx)
275 + anim->filter_frame = av_frame_alloc();
276 + anim->last_width = width;
277 + anim->last_height = height;
278 + anim->last_pixfmt = pixfmt;
283 +static int process_filter_graph(struct anim *anim, AVPicture *dst, const AVPicture *src,
284 + enum AVPixelFormat pixfmt, int width, int height) {
287 + if (!anim->filter_graph || width != anim->last_width ||
288 + height != anim->last_height || pixfmt != anim->last_pixfmt) {
289 + res = init_filter_graph(anim, pixfmt, width, height);
294 + memcpy(anim->filter_frame->data, src->data, sizeof(src->data));
295 + memcpy(anim->filter_frame->linesize, src->linesize, sizeof(src->linesize));
296 + anim->filter_frame->width = width;
297 + anim->filter_frame->height = height;
298 + anim->filter_frame->format = pixfmt;
299 + res = av_buffersrc_add_frame(anim->buffersrc_ctx, anim->filter_frame);
302 + res = av_buffersink_get_frame(anim->buffersink_ctx, anim->filter_frame);
305 + av_picture_copy(dst, (const AVPicture *) anim->filter_frame, pixfmt, width, height);
306 + av_frame_unref(anim->filter_frame);
311 /* postprocess the image in anim->pFrame and do color conversion
312 * and deinterlacing stuff.
317 if (anim->ib_flags & IB_animdeinterlace) {
318 - if (avpicture_deinterlace(
319 + if (process_filter_graph(
322 anim->pFrameDeinterlaced,
326 avpicture_fill((AVPicture *) anim->pFrameRGB,
327 (unsigned char *) ibuf->rect,
328 - PIX_FMT_RGBA, anim->x, anim->y);
329 + AV_PIX_FMT_RGBA, anim->x, anim->y);
331 if (ENDIAN_ORDER == B_ENDIAN) {
332 int *dstStride = anim->pFrameRGB->linesize;
333 @@ -1138,16 +1211,18 @@
335 if (anim == NULL) return;
337 + delete_filter_graph(anim);
339 if (anim->pCodecCtx) {
340 avcodec_close(anim->pCodecCtx);
341 avformat_close_input(&anim->pFormatCtx);
342 - av_free(anim->pFrameRGB);
343 - av_free(anim->pFrame);
344 + av_frame_free(&anim->pFrameRGB);
345 + av_frame_free(&anim->pFrame);
347 if (anim->ib_flags & IB_animdeinterlace) {
348 MEM_freeN(anim->pFrameDeinterlaced->data[0]);
350 - av_free(anim->pFrameDeinterlaced);
351 + av_frame_free(&anim->pFrameDeinterlaced);
352 sws_freeContext(anim->img_convert_ctx);
353 IMB_freeImBuf(anim->last_frame);
354 if (anim->next_packet.stream_index != -1) {
355 diff -ur blender-2.76/source/blender/imbuf/intern/IMB_anim.h blender-2.76.ffmpeg/source/blender/imbuf/intern/IMB_anim.h
356 --- blender-2.76/source/blender/imbuf/intern/IMB_anim.h 2015-10-07 02:09:33.000000000 +0200
357 +++ blender-2.76.ffmpeg/source/blender/imbuf/intern/IMB_anim.h 2016-04-16 15:31:11.527370628 +0200
359 # include <libavformat/avformat.h>
360 # include <libavcodec/avcodec.h>
361 # include <libswscale/swscale.h>
362 +# include <libavfilter/avfilter.h>
363 +# include <libavfilter/buffersrc.h>
364 +# include <libavfilter/buffersink.h>
371 AVPacket next_packet;
373 + AVFilterContext *buffersink_ctx;
374 + AVFilterContext *buffersrc_ctx;
375 + AVFilterGraph *filter_graph;
376 + AVFrame *filter_frame;
379 + enum AVPixelFormat last_pixfmt;
383 diff -ur blender-2.76/source/blender/imbuf/intern/indexer.c blender-2.76.ffmpeg/source/blender/imbuf/intern/indexer.c
384 --- blender-2.76/source/blender/imbuf/intern/indexer.c 2015-10-07 02:09:33.000000000 +0200
385 +++ blender-2.76.ffmpeg/source/blender/imbuf/intern/indexer.c 2016-04-16 15:31:11.527370628 +0200
387 rv->c->pix_fmt = rv->codec->pix_fmts[0];
390 - rv->c->pix_fmt = PIX_FMT_YUVJ420P;
391 + rv->c->pix_fmt = AV_PIX_FMT_YUVJ420P;
394 rv->c->sample_aspect_ratio =
396 if (st->codec->width != width || st->codec->height != height ||
397 st->codec->pix_fmt != rv->c->pix_fmt)
399 - rv->frame = avcodec_alloc_frame();
400 + rv->frame = av_frame_alloc();
401 avpicture_fill((AVPicture *) rv->frame,
402 MEM_mallocN(avpicture_get_size(
405 sws_freeContext(ctx->sws_ctx);
407 MEM_freeN(ctx->frame->data[0]);
408 - av_free(ctx->frame);
409 + av_frame_free(&ctx->frame);
412 get_proxy_filename(ctx->anim, ctx->proxy_size,
415 memset(&next_packet, 0, sizeof(AVPacket));
417 - in_frame = avcodec_alloc_frame();
418 + in_frame = av_frame_alloc();
420 stream_size = avio_size(context->iFormatCtx->pb);
423 } while (frame_finished);
427 + av_frame_free(&in_frame);
431 diff -ur blender-2.76/source/gameengine/VideoTexture/VideoFFmpeg.cpp blender-2.76.ffmpeg/source/gameengine/VideoTexture/VideoFFmpeg.cpp
432 --- blender-2.76/source/gameengine/VideoTexture/VideoFFmpeg.cpp 2015-10-12 00:58:22.000000000 +0200
433 +++ blender-2.76.ffmpeg/source/gameengine/VideoTexture/VideoFFmpeg.cpp 2016-04-16 15:31:11.527370628 +0200
435 BLI_listbase_clear(&m_frameCacheBase);
436 BLI_listbase_clear(&m_packetCacheFree);
437 BLI_listbase_clear(&m_packetCacheBase);
440 + last_pixfmt = AV_PIX_FMT_NONE;
445 VideoFFmpeg::~VideoFFmpeg ()
447 + delete_filter_graph(this);
450 void VideoFFmpeg::refresh(void)
451 @@ -140,23 +145,23 @@
452 AVFrame *VideoFFmpeg::allocFrameRGB()
455 - frame = avcodec_alloc_frame();
456 + frame = av_frame_alloc();
457 if (m_format == RGBA32)
459 avpicture_fill((AVPicture*)frame,
460 (uint8_t*)MEM_callocN(avpicture_get_size(
463 m_codecCtx->width, m_codecCtx->height),
465 - PIX_FMT_RGBA, m_codecCtx->width, m_codecCtx->height);
466 + AV_PIX_FMT_RGBA, m_codecCtx->width, m_codecCtx->height);
469 avpicture_fill((AVPicture*)frame,
470 (uint8_t*)MEM_callocN(avpicture_get_size(
473 m_codecCtx->width, m_codecCtx->height),
475 - PIX_FMT_RGB24, m_codecCtx->width, m_codecCtx->height);
476 + AV_PIX_FMT_RGB24, m_codecCtx->width, m_codecCtx->height);
481 m_codecCtx = codecCtx;
482 m_formatCtx = formatCtx;
483 m_videoStream = videoStream;
484 - m_frame = avcodec_alloc_frame();
485 - m_frameDeinterlaced = avcodec_alloc_frame();
486 + m_frame = av_frame_alloc();
487 + m_frameDeinterlaced = av_frame_alloc();
489 // allocate buffer if deinterlacing is required
490 avpicture_fill((AVPicture*)m_frameDeinterlaced,
491 @@ -248,10 +253,10 @@
492 m_codecCtx->pix_fmt, m_codecCtx->width, m_codecCtx->height);
494 // check if the pixel format supports Alpha
495 - if (m_codecCtx->pix_fmt == PIX_FMT_RGB32 ||
496 - m_codecCtx->pix_fmt == PIX_FMT_BGR32 ||
497 - m_codecCtx->pix_fmt == PIX_FMT_RGB32_1 ||
498 - m_codecCtx->pix_fmt == PIX_FMT_BGR32_1)
499 + if (m_codecCtx->pix_fmt == AV_PIX_FMT_RGB32 ||
500 + m_codecCtx->pix_fmt == AV_PIX_FMT_BGR32 ||
501 + m_codecCtx->pix_fmt == AV_PIX_FMT_RGB32_1 ||
502 + m_codecCtx->pix_fmt == AV_PIX_FMT_BGR32_1)
504 // allocate buffer to store final decoded frame
524 @@ -293,13 +298,81 @@
525 av_free(m_frameDeinterlaced);
526 m_frameDeinterlaced = NULL;
527 MEM_freeN(m_frameRGB->data[0]);
528 - av_free(m_frameRGB);
529 + av_frame_free(&m_frameRGB);
536 +void VideoFFmpeg::delete_filter_graph(VideoFFmpeg* video) {
537 + if (video->filter_graph) {
538 + av_frame_free(&video->filter_frame);
539 + avfilter_graph_free(&video->filter_graph);
543 +int VideoFFmpeg::init_filter_graph(VideoFFmpeg* video, enum AVPixelFormat pixfmt, int width, int height) {
544 + AVFilterInOut *inputs = NULL, *outputs = NULL;
548 + delete_filter_graph(video);
549 + video->filter_graph = avfilter_graph_alloc();
550 + snprintf(args, sizeof(args),
551 + "buffer=video_size=%dx%d:pix_fmt=%d:time_base=1/1:pixel_aspect=0/1[in];"
554 + width, height, pixfmt);
555 + res = avfilter_graph_parse2(video->filter_graph, args, &inputs, &outputs);
558 + if(inputs || outputs)
560 + res = avfilter_graph_config(video->filter_graph, NULL);
564 + video->buffersrc_ctx = avfilter_graph_get_filter(video->filter_graph, "Parsed_buffer_0");
565 + video->buffersink_ctx = avfilter_graph_get_filter(video->filter_graph, "Parsed_buffersink_2");
566 + if (!video->buffersrc_ctx || !video->buffersink_ctx)
568 + video->filter_frame = av_frame_alloc();
569 + video->last_width = width;
570 + video->last_height = height;
571 + video->last_pixfmt = pixfmt;
576 +int VideoFFmpeg::process_filter_graph(VideoFFmpeg* video, AVPicture *dst, const AVPicture *src,
577 + enum AVPixelFormat pixfmt, int width, int height) {
580 + if (!video->filter_graph || width != video->last_width ||
581 + height != video->last_height || pixfmt != video->last_pixfmt) {
582 + res = init_filter_graph(video, pixfmt, width, height);
587 + memcpy(video->filter_frame->data, src->data, sizeof(src->data));
588 + memcpy(video->filter_frame->linesize, src->linesize, sizeof(src->linesize));
589 + video->filter_frame->width = width;
590 + video->filter_frame->height = height;
591 + video->filter_frame->format = pixfmt;
592 + res = av_buffersrc_add_frame(video->buffersrc_ctx, video->filter_frame);
595 + res = av_buffersink_get_frame(video->buffersink_ctx, video->filter_frame);
598 + av_picture_copy(dst, (const AVPicture *) video->filter_frame, pixfmt, width, height);
599 + av_frame_unref(video->filter_frame);
605 * This thread is used to load video frame asynchronously.
606 * It provides a frame caching service.
609 if (video->m_deinterlace)
611 - if (avpicture_deinterlace(
612 + if (process_filter_graph(video,
613 (AVPicture*) video->m_frameDeinterlaced,
614 (const AVPicture*) video->m_frame,
615 video->m_codecCtx->pix_fmt,
616 @@ -486,14 +559,14 @@
618 BLI_remlink(&m_frameCacheBase, frame);
619 MEM_freeN(frame->frame->data[0]);
620 - av_free(frame->frame);
621 + av_frame_free(&frame->frame);
624 while ((frame = (CacheFrame *)m_frameCacheFree.first) != NULL)
626 BLI_remlink(&m_frameCacheFree, frame);
627 MEM_freeN(frame->frame->data[0]);
628 - av_free(frame->frame);
629 + av_frame_free(&frame->frame);
632 while ((packet = (CachePacket *)m_packetCacheBase.first) != NULL)
633 @@ -1057,7 +1130,7 @@
637 - if (avpicture_deinterlace(
638 + if (process_filter_graph(this,
639 (AVPicture*) m_frameDeinterlaced,
640 (const AVPicture*) m_frame,
642 diff -ur blender-2.76/source/gameengine/VideoTexture/VideoFFmpeg.h blender-2.76.ffmpeg/source/gameengine/VideoTexture/VideoFFmpeg.h
643 --- blender-2.76/source/gameengine/VideoTexture/VideoFFmpeg.h 2015-10-10 10:20:56.000000000 +0200
644 +++ blender-2.76.ffmpeg/source/gameengine/VideoTexture/VideoFFmpeg.h 2016-04-16 15:31:11.527370628 +0200
648 #include "ffmpeg_compat.h"
649 +#include <libavfilter/avfilter.h>
650 +#include <libavfilter/buffersrc.h>
651 +#include <libavfilter/buffersink.h>
652 #include "DNA_listBase.h"
653 #include "BLI_threads.h"
654 #include "BLI_blenlib.h"
657 AVFrame *allocFrameRGB();
658 static void *cacheThread(void *);
660 + AVFilterContext *buffersink_ctx;
661 + AVFilterContext *buffersrc_ctx;
662 + AVFilterGraph *filter_graph;
663 + AVFrame *filter_frame;
666 + enum AVPixelFormat last_pixfmt;
668 + static void delete_filter_graph(VideoFFmpeg* video);
669 + static int init_filter_graph(VideoFFmpeg* video, enum AVPixelFormat pixfmt, int width, int height);
670 + static int process_filter_graph(VideoFFmpeg* video, AVPicture *dst, const AVPicture *src, enum AVPixelFormat pixfmt, int width, int height);
673 inline VideoFFmpeg *getFFmpeg(PyImage *self)