diff -ur blender-2.76/CMakeLists.txt blender-2.76.ffmpeg/CMakeLists.txt --- blender-2.76/CMakeLists.txt 2015-10-12 00:58:22.000000000 +0200 +++ blender-2.76.ffmpeg/CMakeLists.txt 2016-04-16 15:31:11.524037254 +0200 @@ -982,7 +982,7 @@ if(WITH_CODEC_FFMPEG) set(FFMPEG /usr CACHE PATH "FFMPEG Directory") - set(FFMPEG_LIBRARIES avformat avcodec avutil avdevice swscale CACHE STRING "FFMPEG Libraries") + set(FFMPEG_LIBRARIES avformat avcodec avutil avdevice swscale avfilter CACHE STRING "FFMPEG Libraries") mark_as_advanced(FFMPEG) diff -ur blender-2.76/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp blender-2.76.ffmpeg/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp --- blender-2.76/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp 2015-10-07 02:09:33.000000000 +0200 +++ blender-2.76.ffmpeg/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp 2016-04-16 15:31:11.524037254 +0200 @@ -58,9 +58,9 @@ got_frame = 0; if(!frame) - frame = avcodec_alloc_frame(); + frame = av_frame_alloc(); else - avcodec_get_frame_defaults(frame); + av_frame_unref(frame); read_length = avcodec_decode_audio4(m_codecCtx, frame, &got_frame, &packet); if(read_length < 0) diff -ur blender-2.76/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp blender-2.76.ffmpeg/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp --- blender-2.76/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp 2015-10-07 02:09:33.000000000 +0200 +++ blender-2.76.ffmpeg/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp 2016-04-16 15:31:11.524037254 +0200 @@ -202,7 +202,7 @@ m_frame = av_frame_alloc(); if (!m_frame) AUD_THROW(AUD_ERROR_FFMPEG, codec_error); - avcodec_get_frame_defaults(m_frame); + av_frame_unref(m_frame); m_frame->linesize[0] = m_input_size * samplesize; m_frame->format = m_codecCtx->sample_fmt; m_frame->nb_samples = m_input_size; diff -ur blender-2.76/source/blender/blenkernel/intern/writeffmpeg.c blender-2.76.ffmpeg/source/blender/blenkernel/intern/writeffmpeg.c --- blender-2.76/source/blender/blenkernel/intern/writeffmpeg.c 2015-10-12 00:58:22.000000000 +0200 +++ blender-2.76.ffmpeg/source/blender/blenkernel/intern/writeffmpeg.c 2016-04-16 15:31:11.527370628 +0200 @@ -138,8 +138,8 @@ context->audio_time += (double) context->audio_input_samples / (double) c->sample_rate; #ifdef FFMPEG_HAVE_ENCODE_AUDIO2 - frame = avcodec_alloc_frame(); - avcodec_get_frame_defaults(frame); + frame = av_frame_alloc(); + av_frame_unref(frame); frame->pts = context->audio_time / av_q2d(c->time_base); frame->nb_samples = context->audio_input_samples; frame->format = c->sample_fmt; @@ -172,7 +172,7 @@ } if (!got_output) { - avcodec_free_frame(&frame); + av_frame_free(&frame); return 0; } #else @@ -202,7 +202,7 @@ if (av_interleaved_write_frame(context->outfile, &pkt) != 0) { fprintf(stderr, "Error writing audio packet!\n"); if (frame) - avcodec_free_frame(&frame); + av_frame_free(&frame); return -1; } @@ -210,7 +210,7 @@ } if (frame) - avcodec_free_frame(&frame); + av_frame_free(&frame); return 0; } @@ -224,7 +224,7 @@ int size; /* allocate space for the struct */ - f = avcodec_alloc_frame(); + f = av_frame_alloc(); if (!f) return NULL; size = avpicture_get_size(pix_fmt, width, height); /* allocate the actual picture buffer */ @@ -363,8 +363,8 @@ int height = c->height; AVFrame *rgb_frame; - if (c->pix_fmt != PIX_FMT_BGR32) { - rgb_frame = alloc_picture(PIX_FMT_BGR32, width, height); + if (c->pix_fmt != AV_PIX_FMT_BGR32) { + rgb_frame = alloc_picture(AV_PIX_FMT_BGR32, width, height); if (!rgb_frame) { BKE_report(reports, RPT_ERROR, "Could not allocate temporary frame"); return NULL; @@ -414,14 +414,14 @@ } } - if (c->pix_fmt != PIX_FMT_BGR32) { + if (c->pix_fmt != AV_PIX_FMT_BGR32) { sws_scale(context->img_convert_ctx, (const uint8_t *const *) rgb_frame->data, rgb_frame->linesize, 0, c->height, context->current_frame->data, context->current_frame->linesize); delete_picture(rgb_frame); } - context->current_frame->format = PIX_FMT_BGR32; + context->current_frame->format = AV_PIX_FMT_BGR32; context->current_frame->width = width; context->current_frame->height = height; @@ -586,12 +586,12 @@ } else { /* makes HuffYUV happy ... */ - c->pix_fmt = PIX_FMT_YUV422P; + c->pix_fmt = AV_PIX_FMT_YUV422P; } if (context->ffmpeg_type == FFMPEG_XVID) { /* arghhhh ... */ - c->pix_fmt = PIX_FMT_YUV420P; + c->pix_fmt = AV_PIX_FMT_YUV420P; c->codec_tag = (('D' << 24) + ('I' << 16) + ('V' << 8) + 'X'); } @@ -604,26 +604,26 @@ /* Keep lossless encodes in the RGB domain. */ if (codec_id == AV_CODEC_ID_HUFFYUV) { if (rd->im_format.planes == R_IMF_PLANES_RGBA) { - c->pix_fmt = PIX_FMT_BGRA; + c->pix_fmt = AV_PIX_FMT_BGRA; } else { - c->pix_fmt = PIX_FMT_RGB32; + c->pix_fmt = AV_PIX_FMT_RGB32; } } if (codec_id == AV_CODEC_ID_FFV1) { - c->pix_fmt = PIX_FMT_RGB32; + c->pix_fmt = AV_PIX_FMT_RGB32; } if (codec_id == AV_CODEC_ID_QTRLE) { if (rd->im_format.planes == R_IMF_PLANES_RGBA) { - c->pix_fmt = PIX_FMT_ARGB; + c->pix_fmt = AV_PIX_FMT_ARGB; } } if (codec_id == AV_CODEC_ID_PNG) { if (rd->im_format.planes == R_IMF_PLANES_RGBA) { - c->pix_fmt = PIX_FMT_RGBA; + c->pix_fmt = AV_PIX_FMT_RGBA; } } @@ -661,7 +661,7 @@ context->current_frame = alloc_picture(c->pix_fmt, c->width, c->height); - context->img_convert_ctx = sws_getContext(c->width, c->height, PIX_FMT_BGR32, c->width, c->height, c->pix_fmt, SWS_BICUBIC, + context->img_convert_ctx = sws_getContext(c->width, c->height, AV_PIX_FMT_BGR32, c->width, c->height, c->pix_fmt, SWS_BICUBIC, NULL, NULL, NULL); return st; } diff -ur blender-2.76/source/blender/imbuf/intern/anim_movie.c blender-2.76.ffmpeg/source/blender/imbuf/intern/anim_movie.c --- blender-2.76/source/blender/imbuf/intern/anim_movie.c 2015-10-07 02:09:33.000000000 +0200 +++ blender-2.76.ffmpeg/source/blender/imbuf/intern/anim_movie.c 2016-04-16 15:31:11.527370628 +0200 @@ -474,6 +474,10 @@ const int *inv_table; #endif + anim->last_width = -1; + anim->last_height = -1; + anim->last_pixfmt = AV_PIX_FMT_NONE; + if (anim == NULL) return(-1); streamcount = anim->streamindex; @@ -562,21 +566,21 @@ anim->next_pts = -1; anim->next_packet.stream_index = -1; - anim->pFrame = avcodec_alloc_frame(); + anim->pFrame = av_frame_alloc(); anim->pFrameComplete = false; - anim->pFrameDeinterlaced = avcodec_alloc_frame(); - anim->pFrameRGB = avcodec_alloc_frame(); + anim->pFrameDeinterlaced = av_frame_alloc(); + anim->pFrameRGB = av_frame_alloc(); - if (avpicture_get_size(PIX_FMT_RGBA, anim->x, anim->y) != + if (avpicture_get_size(AV_PIX_FMT_RGBA, anim->x, anim->y) != anim->x * anim->y * 4) { fprintf(stderr, "ffmpeg has changed alloc scheme ... ARGHHH!\n"); avcodec_close(anim->pCodecCtx); avformat_close_input(&anim->pFormatCtx); - av_free(anim->pFrameRGB); - av_free(anim->pFrameDeinterlaced); - av_free(anim->pFrame); + av_frame_free(&anim->pFrameRGB); + av_frame_free(&anim->pFrameDeinterlaced); + av_frame_free(&anim->pFrame); anim->pCodecCtx = NULL; return -1; } @@ -606,7 +610,7 @@ anim->pCodecCtx->pix_fmt, anim->x, anim->y, - PIX_FMT_RGBA, + AV_PIX_FMT_RGBA, SWS_FAST_BILINEAR | SWS_PRINT_INFO | SWS_FULL_CHR_H_INT, NULL, NULL, NULL); @@ -615,9 +619,9 @@ "Can't transform color space??? Bailing out...\n"); avcodec_close(anim->pCodecCtx); avformat_close_input(&anim->pFormatCtx); - av_free(anim->pFrameRGB); - av_free(anim->pFrameDeinterlaced); - av_free(anim->pFrame); + av_frame_free(&anim->pFrameRGB); + av_frame_free(&anim->pFrameDeinterlaced); + av_frame_free(&anim->pFrame); anim->pCodecCtx = NULL; return -1; } @@ -644,6 +648,74 @@ return (0); } +static void delete_filter_graph(struct anim *anim) { + if (anim->filter_graph) { + av_frame_free(&anim->filter_frame); + avfilter_graph_free(&anim->filter_graph); + } +} + +static int init_filter_graph(struct anim *anim, enum AVPixelFormat pixfmt, int width, int height) { + AVFilterInOut *inputs = NULL, *outputs = NULL; + char args[512]; + int res; + + delete_filter_graph(anim); + anim->filter_graph = avfilter_graph_alloc(); + snprintf(args, sizeof(args), + "buffer=video_size=%dx%d:pix_fmt=%d:time_base=1/1:pixel_aspect=0/1[in];" + "[in]yadif[out];" + "[out]buffersink", + width, height, pixfmt); + res = avfilter_graph_parse2(anim->filter_graph, args, &inputs, &outputs); + if (res < 0) + return res; + if(inputs || outputs) + return -1; + res = avfilter_graph_config(anim->filter_graph, NULL); + if (res < 0) + return res; + + anim->buffersrc_ctx = avfilter_graph_get_filter(anim->filter_graph, "Parsed_buffer_0"); + anim->buffersink_ctx = avfilter_graph_get_filter(anim->filter_graph, "Parsed_buffersink_2"); + if (!anim->buffersrc_ctx || !anim->buffersink_ctx) + return -1; + anim->filter_frame = av_frame_alloc(); + anim->last_width = width; + anim->last_height = height; + anim->last_pixfmt = pixfmt; + + return 0; +} + +static int process_filter_graph(struct anim *anim, AVPicture *dst, const AVPicture *src, + enum AVPixelFormat pixfmt, int width, int height) { + int res; + + if (!anim->filter_graph || width != anim->last_width || + height != anim->last_height || pixfmt != anim->last_pixfmt) { + res = init_filter_graph(anim, pixfmt, width, height); + if (res < 0) + return res; + } + + memcpy(anim->filter_frame->data, src->data, sizeof(src->data)); + memcpy(anim->filter_frame->linesize, src->linesize, sizeof(src->linesize)); + anim->filter_frame->width = width; + anim->filter_frame->height = height; + anim->filter_frame->format = pixfmt; + res = av_buffersrc_add_frame(anim->buffersrc_ctx, anim->filter_frame); + if (res < 0) + return res; + res = av_buffersink_get_frame(anim->buffersink_ctx, anim->filter_frame); + if (res < 0) + return res; + av_picture_copy(dst, (const AVPicture *) anim->filter_frame, pixfmt, width, height); + av_frame_unref(anim->filter_frame); + + return 0; +} + /* postprocess the image in anim->pFrame and do color conversion * and deinterlacing stuff. * @@ -677,7 +749,8 @@ if (anim->ib_flags & IB_animdeinterlace) { - if (avpicture_deinterlace( + if (process_filter_graph( + anim, (AVPicture *) anim->pFrameDeinterlaced, (const AVPicture *) @@ -695,7 +768,7 @@ avpicture_fill((AVPicture *) anim->pFrameRGB, (unsigned char *) ibuf->rect, - PIX_FMT_RGBA, anim->x, anim->y); + AV_PIX_FMT_RGBA, anim->x, anim->y); if (ENDIAN_ORDER == B_ENDIAN) { int *dstStride = anim->pFrameRGB->linesize; @@ -1138,16 +1211,18 @@ { if (anim == NULL) return; + delete_filter_graph(anim); + if (anim->pCodecCtx) { avcodec_close(anim->pCodecCtx); avformat_close_input(&anim->pFormatCtx); - av_free(anim->pFrameRGB); - av_free(anim->pFrame); + av_frame_free(&anim->pFrameRGB); + av_frame_free(&anim->pFrame); if (anim->ib_flags & IB_animdeinterlace) { MEM_freeN(anim->pFrameDeinterlaced->data[0]); } - av_free(anim->pFrameDeinterlaced); + av_frame_free(&anim->pFrameDeinterlaced); sws_freeContext(anim->img_convert_ctx); IMB_freeImBuf(anim->last_frame); if (anim->next_packet.stream_index != -1) { diff -ur blender-2.76/source/blender/imbuf/intern/IMB_anim.h blender-2.76.ffmpeg/source/blender/imbuf/intern/IMB_anim.h --- blender-2.76/source/blender/imbuf/intern/IMB_anim.h 2015-10-07 02:09:33.000000000 +0200 +++ blender-2.76.ffmpeg/source/blender/imbuf/intern/IMB_anim.h 2016-04-16 15:31:11.527370628 +0200 @@ -76,6 +76,9 @@ # include # include # include +# include +# include +# include #endif #ifdef WITH_REDCODE @@ -175,6 +178,14 @@ int64_t last_pts; int64_t next_pts; AVPacket next_packet; + + AVFilterContext *buffersink_ctx; + AVFilterContext *buffersrc_ctx; + AVFilterGraph *filter_graph; + AVFrame *filter_frame; + int last_width; + int last_height; + enum AVPixelFormat last_pixfmt; #endif #ifdef WITH_REDCODE diff -ur blender-2.76/source/blender/imbuf/intern/indexer.c blender-2.76.ffmpeg/source/blender/imbuf/intern/indexer.c --- blender-2.76/source/blender/imbuf/intern/indexer.c 2015-10-07 02:09:33.000000000 +0200 +++ blender-2.76.ffmpeg/source/blender/imbuf/intern/indexer.c 2016-04-16 15:31:11.527370628 +0200 @@ -519,7 +519,7 @@ rv->c->pix_fmt = rv->codec->pix_fmts[0]; } else { - rv->c->pix_fmt = PIX_FMT_YUVJ420P; + rv->c->pix_fmt = AV_PIX_FMT_YUVJ420P; } rv->c->sample_aspect_ratio = @@ -554,7 +554,7 @@ if (st->codec->width != width || st->codec->height != height || st->codec->pix_fmt != rv->c->pix_fmt) { - rv->frame = avcodec_alloc_frame(); + rv->frame = av_frame_alloc(); avpicture_fill((AVPicture *) rv->frame, MEM_mallocN(avpicture_get_size( rv->c->pix_fmt, @@ -675,7 +675,7 @@ sws_freeContext(ctx->sws_ctx); MEM_freeN(ctx->frame->data[0]); - av_free(ctx->frame); + av_frame_free(&ctx->frame); } get_proxy_filename(ctx->anim, ctx->proxy_size, @@ -905,7 +905,7 @@ memset(&next_packet, 0, sizeof(AVPacket)); - in_frame = avcodec_alloc_frame(); + in_frame = av_frame_alloc(); stream_size = avio_size(context->iFormatCtx->pb); @@ -973,7 +973,7 @@ } while (frame_finished); } - av_free(in_frame); + av_frame_free(&in_frame); return 1; } diff -ur blender-2.76/source/gameengine/VideoTexture/VideoFFmpeg.cpp blender-2.76.ffmpeg/source/gameengine/VideoTexture/VideoFFmpeg.cpp --- blender-2.76/source/gameengine/VideoTexture/VideoFFmpeg.cpp 2015-10-12 00:58:22.000000000 +0200 +++ blender-2.76.ffmpeg/source/gameengine/VideoTexture/VideoFFmpeg.cpp 2016-04-16 15:31:11.527370628 +0200 @@ -79,11 +79,16 @@ BLI_listbase_clear(&m_frameCacheBase); BLI_listbase_clear(&m_packetCacheFree); BLI_listbase_clear(&m_packetCacheBase); + last_width = -1; + last_height = -1; + last_pixfmt = AV_PIX_FMT_NONE; + } // destructor VideoFFmpeg::~VideoFFmpeg () { + delete_filter_graph(this); } void VideoFFmpeg::refresh(void) @@ -140,23 +145,23 @@ AVFrame *VideoFFmpeg::allocFrameRGB() { AVFrame *frame; - frame = avcodec_alloc_frame(); + frame = av_frame_alloc(); if (m_format == RGBA32) { avpicture_fill((AVPicture*)frame, (uint8_t*)MEM_callocN(avpicture_get_size( - PIX_FMT_RGBA, + AV_PIX_FMT_RGBA, m_codecCtx->width, m_codecCtx->height), "ffmpeg rgba"), - PIX_FMT_RGBA, m_codecCtx->width, m_codecCtx->height); + AV_PIX_FMT_RGBA, m_codecCtx->width, m_codecCtx->height); } else { avpicture_fill((AVPicture*)frame, (uint8_t*)MEM_callocN(avpicture_get_size( - PIX_FMT_RGB24, + AV_PIX_FMT_RGB24, m_codecCtx->width, m_codecCtx->height), "ffmpeg rgb"), - PIX_FMT_RGB24, m_codecCtx->width, m_codecCtx->height); + AV_PIX_FMT_RGB24, m_codecCtx->width, m_codecCtx->height); } return frame; } @@ -236,8 +241,8 @@ m_codecCtx = codecCtx; m_formatCtx = formatCtx; m_videoStream = videoStream; - m_frame = avcodec_alloc_frame(); - m_frameDeinterlaced = avcodec_alloc_frame(); + m_frame = av_frame_alloc(); + m_frameDeinterlaced = av_frame_alloc(); // allocate buffer if deinterlacing is required avpicture_fill((AVPicture*)m_frameDeinterlaced, @@ -248,10 +253,10 @@ m_codecCtx->pix_fmt, m_codecCtx->width, m_codecCtx->height); // check if the pixel format supports Alpha - if (m_codecCtx->pix_fmt == PIX_FMT_RGB32 || - m_codecCtx->pix_fmt == PIX_FMT_BGR32 || - m_codecCtx->pix_fmt == PIX_FMT_RGB32_1 || - m_codecCtx->pix_fmt == PIX_FMT_BGR32_1) + if (m_codecCtx->pix_fmt == AV_PIX_FMT_RGB32 || + m_codecCtx->pix_fmt == AV_PIX_FMT_BGR32 || + m_codecCtx->pix_fmt == AV_PIX_FMT_RGB32_1 || + m_codecCtx->pix_fmt == AV_PIX_FMT_BGR32_1) { // allocate buffer to store final decoded frame m_format = RGBA32; @@ -262,7 +267,7 @@ m_codecCtx->pix_fmt, m_codecCtx->width, m_codecCtx->height, - PIX_FMT_RGBA, + AV_PIX_FMT_RGBA, SWS_FAST_BILINEAR, NULL, NULL, NULL); } else @@ -276,7 +281,7 @@ m_codecCtx->pix_fmt, m_codecCtx->width, m_codecCtx->height, - PIX_FMT_RGB24, + AV_PIX_FMT_RGB24, SWS_FAST_BILINEAR, NULL, NULL, NULL); } @@ -293,13 +298,81 @@ av_free(m_frameDeinterlaced); m_frameDeinterlaced = NULL; MEM_freeN(m_frameRGB->data[0]); - av_free(m_frameRGB); + av_frame_free(&m_frameRGB); m_frameRGB = NULL; return -1; } return 0; } +void VideoFFmpeg::delete_filter_graph(VideoFFmpeg* video) { + if (video->filter_graph) { + av_frame_free(&video->filter_frame); + avfilter_graph_free(&video->filter_graph); + } +} + +int VideoFFmpeg::init_filter_graph(VideoFFmpeg* video, enum AVPixelFormat pixfmt, int width, int height) { + AVFilterInOut *inputs = NULL, *outputs = NULL; + char args[512]; + int res; + + delete_filter_graph(video); + video->filter_graph = avfilter_graph_alloc(); + snprintf(args, sizeof(args), + "buffer=video_size=%dx%d:pix_fmt=%d:time_base=1/1:pixel_aspect=0/1[in];" + "[in]yadif[out];" + "[out]buffersink", + width, height, pixfmt); + res = avfilter_graph_parse2(video->filter_graph, args, &inputs, &outputs); + if (res < 0) + return res; + if(inputs || outputs) + return -1; + res = avfilter_graph_config(video->filter_graph, NULL); + if (res < 0) + return res; + + video->buffersrc_ctx = avfilter_graph_get_filter(video->filter_graph, "Parsed_buffer_0"); + video->buffersink_ctx = avfilter_graph_get_filter(video->filter_graph, "Parsed_buffersink_2"); + if (!video->buffersrc_ctx || !video->buffersink_ctx) + return -1; + video->filter_frame = av_frame_alloc(); + video->last_width = width; + video->last_height = height; + video->last_pixfmt = pixfmt; + + return 0; +} + +int VideoFFmpeg::process_filter_graph(VideoFFmpeg* video, AVPicture *dst, const AVPicture *src, + enum AVPixelFormat pixfmt, int width, int height) { + int res; + + if (!video->filter_graph || width != video->last_width || + height != video->last_height || pixfmt != video->last_pixfmt) { + res = init_filter_graph(video, pixfmt, width, height); + if (res < 0) + return res; + } + + memcpy(video->filter_frame->data, src->data, sizeof(src->data)); + memcpy(video->filter_frame->linesize, src->linesize, sizeof(src->linesize)); + video->filter_frame->width = width; + video->filter_frame->height = height; + video->filter_frame->format = pixfmt; + res = av_buffersrc_add_frame(video->buffersrc_ctx, video->filter_frame); + if (res < 0) + return res; + res = av_buffersink_get_frame(video->buffersink_ctx, video->filter_frame); + if (res < 0) + return res; + av_picture_copy(dst, (const AVPicture *) video->filter_frame, pixfmt, width, height); + av_frame_unref(video->filter_frame); + + return 0; +} + /* * This thread is used to load video frame asynchronously. * It provides a frame caching service. @@ -392,7 +465,7 @@ { if (video->m_deinterlace) { - if (avpicture_deinterlace( + if (process_filter_graph(video, (AVPicture*) video->m_frameDeinterlaced, (const AVPicture*) video->m_frame, video->m_codecCtx->pix_fmt, @@ -486,14 +559,14 @@ { BLI_remlink(&m_frameCacheBase, frame); MEM_freeN(frame->frame->data[0]); - av_free(frame->frame); + av_frame_free(&frame->frame); delete frame; } while ((frame = (CacheFrame *)m_frameCacheFree.first) != NULL) { BLI_remlink(&m_frameCacheFree, frame); MEM_freeN(frame->frame->data[0]); - av_free(frame->frame); + av_frame_free(&frame->frame); delete frame; } while ((packet = (CachePacket *)m_packetCacheBase.first) != NULL) @@ -1057,7 +1130,7 @@ if (m_deinterlace) { - if (avpicture_deinterlace( + if (process_filter_graph(this, (AVPicture*) m_frameDeinterlaced, (const AVPicture*) m_frame, m_codecCtx->pix_fmt, diff -ur blender-2.76/source/gameengine/VideoTexture/VideoFFmpeg.h blender-2.76.ffmpeg/source/gameengine/VideoTexture/VideoFFmpeg.h --- blender-2.76/source/gameengine/VideoTexture/VideoFFmpeg.h 2015-10-10 10:20:56.000000000 +0200 +++ blender-2.76.ffmpeg/source/gameengine/VideoTexture/VideoFFmpeg.h 2016-04-16 15:31:11.527370628 +0200 @@ -39,6 +39,9 @@ extern "C" { #include #include "ffmpeg_compat.h" +#include +#include +#include #include "DNA_listBase.h" #include "BLI_threads.h" #include "BLI_blenlib.h" @@ -207,6 +210,18 @@ AVFrame *allocFrameRGB(); static void *cacheThread(void *); + + AVFilterContext *buffersink_ctx; + AVFilterContext *buffersrc_ctx; + AVFilterGraph *filter_graph; + AVFrame *filter_frame; + int last_width; + int last_height; + enum AVPixelFormat last_pixfmt; + + static void delete_filter_graph(VideoFFmpeg* video); + static int init_filter_graph(VideoFFmpeg* video, enum AVPixelFormat pixfmt, int width, int height); + static int process_filter_graph(VideoFFmpeg* video, AVPicture *dst, const AVPicture *src, enum AVPixelFormat pixfmt, int width, int height); }; inline VideoFFmpeg *getFFmpeg(PyImage *self)