From 4b4c931b7b604d12e0e182241fe64ee0e3179142 Mon Sep 17 00:00:00 2001 From: alihanozturk Date: Thu, 25 Aug 2016 22:18:54 +0300 Subject: [PATCH] blender add ffmpeg3 patch --- multimedia/editor/blender/files/ffmpeg3.patch | 673 ++++++++++++++++++ multimedia/editor/blender/pspec.xml | 1 + 2 files changed, 674 insertions(+) create mode 100644 multimedia/editor/blender/files/ffmpeg3.patch diff --git a/multimedia/editor/blender/files/ffmpeg3.patch b/multimedia/editor/blender/files/ffmpeg3.patch new file mode 100644 index 0000000000..ab770269c8 --- /dev/null +++ b/multimedia/editor/blender/files/ffmpeg3.patch @@ -0,0 +1,673 @@ +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) diff --git a/multimedia/editor/blender/pspec.xml b/multimedia/editor/blender/pspec.xml index e3dbeb5456..12a0757cb0 100644 --- a/multimedia/editor/blender/pspec.xml +++ b/multimedia/editor/blender/pspec.xml @@ -49,6 +49,7 @@ 06-blender-2.68-fix-install-rules.patch + ffmpeg3.patch