[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [56046] trunk/blender: == FFMPEG / Canon DSLR footage workaround ==

Peter Schlaile peter at schlaile.de
Sun Apr 14 15:44:04 CEST 2013


Revision: 56046
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=56046
Author:   schlaile
Date:     2013-04-14 13:44:04 +0000 (Sun, 14 Apr 2013)
Log Message:
-----------
== FFMPEG / Canon DSLR footage workaround ==

The latest ffmpeg versions include a workaround to deal with a certain
pecularity in Canon DSLR footage: instead of decoding pictures with the
proper resolution of 1920x1080 they decode it with 1920x1088 and add a
black bar at the bottom.

Needless to say, that this screws up things in a lot of areas within blender
(proxy indices, mask animations etc.)

Since all blender versions besides Linux x86 32bit seem still to include
older ffmpeg versions which still contain this bug, this patch adds
a workaround for older versions until we have all versions on all platforms
up to date.

See also: http://git.libav.org/?p=libav.git;a=commit;h=30f515091c323da59c0f1b533703dedca2f4b95d

Modified Paths:
--------------
    trunk/blender/intern/ffmpeg/ffmpeg_compat.h
    trunk/blender/source/blender/imbuf/intern/anim_movie.c
    trunk/blender/source/blender/imbuf/intern/indexer.c

Modified: trunk/blender/intern/ffmpeg/ffmpeg_compat.h
===================================================================
--- trunk/blender/intern/ffmpeg/ffmpeg_compat.h	2013-04-14 12:01:12 UTC (rev 56045)
+++ trunk/blender/intern/ffmpeg/ffmpeg_compat.h	2013-04-14 13:44:04 UTC (rev 56046)
@@ -72,11 +72,43 @@
 #define FFMPEG_SWSCALE_COLOR_SPACE_SUPPORT
 #endif
 
+#if ((LIBAVCODEC_VERSION_MAJOR > 54) || (LIBAVCODEC_VERSION_MAJOR >= 54) && (LIBAVCODEC_VERSION_MINOR > 14))
+#define FFMPEG_HAVE_CANON_H264_RESOLUTION_FIX
+#endif
+
 #if ((LIBAVUTIL_VERSION_MAJOR > 51) || (LIBAVUTIL_VERSION_MAJOR == 51) && (LIBAVUTIL_VERSION_MINOR >= 32))
 #define FFMPEG_FFV1_ALPHA_SUPPORTED
 #define FFMPEG_SAMPLE_FMT_S16P_SUPPORTED
 #endif
 
+static inline
+int av_get_cropped_height_from_codec(AVCodecContext *pCodecCtx)
+{
+	int y = pCodecCtx->height;
+
+#ifndef FFMPEG_HAVE_CANON_H264_RESOLUTION_FIX
+/* really bad hack to remove this dreadfull black bar at the bottom
+   with Canon footage and old ffmpeg versions.
+   (to fix this properly in older ffmpeg versions one has to write a new
+   demuxer...) 
+	   
+   see the actual fix here for reference:
+
+   http://git.libav.org/?p=libav.git;a=commit;h=30f515091c323da59c0f1b533703dedca2f4b95d
+
+   We do our best to apply this only to matching footage.
+*/
+	if (pCodecCtx->width == 1920 && 
+	    pCodecCtx->height == 1088 &&
+	    pCodecCtx->pix_fmt == PIX_FMT_YUVJ420P &&
+	    pCodecCtx->codec_id == CODEC_ID_H264 ) {
+		y = 1080;
+	}
+#endif
+
+	return y;
+}
+
 #if ((LIBAVUTIL_VERSION_MAJOR < 51) || (LIBAVUTIL_VERSION_MAJOR == 51) && (LIBAVUTIL_VERSION_MINOR < 22))
 static inline
 int av_opt_set(void *obj, const char *name, const char *val, int search_flags)

Modified: trunk/blender/source/blender/imbuf/intern/anim_movie.c
===================================================================
--- trunk/blender/source/blender/imbuf/intern/anim_movie.c	2013-04-14 12:01:12 UTC (rev 56045)
+++ trunk/blender/source/blender/imbuf/intern/anim_movie.c	2013-04-14 13:44:04 UTC (rev 56046)
@@ -548,7 +548,13 @@
 	anim->params = 0;
 
 	anim->x = pCodecCtx->width;
-	anim->y = pCodecCtx->height;
+	anim->y = av_get_cropped_height_from_codec(pCodecCtx);
+
+	anim->pFormatCtx = pFormatCtx;
+	anim->pCodecCtx = pCodecCtx;
+	anim->pCodec = pCodec;
+	anim->videoStream = videoStream;
+
 	anim->interlacing = 0;
 	anim->orientation = 0;
 	anim->framesize = anim->x * anim->y * 4;
@@ -559,11 +565,6 @@
 	anim->next_pts = -1;
 	anim->next_packet.stream_index = -1;
 
-	anim->pFormatCtx = pFormatCtx;
-	anim->pCodecCtx = pCodecCtx;
-	anim->pCodec = pCodec;
-	anim->videoStream = videoStream;
-
 	anim->pFrame = avcodec_alloc_frame();
 	anim->pFrameComplete = FALSE;
 	anim->pFrameDeinterlaced = avcodec_alloc_frame();
@@ -587,9 +588,12 @@
 		avpicture_fill((AVPicture *) anim->pFrameDeinterlaced,
 		               MEM_callocN(avpicture_get_size(
 		                               anim->pCodecCtx->pix_fmt,
-		                               anim->x, anim->y),
+					       anim->pCodecCtx->width,
+					       anim->pCodecCtx->height),
 		                           "ffmpeg deinterlace"),
-		               anim->pCodecCtx->pix_fmt, anim->x, anim->y);
+		               anim->pCodecCtx->pix_fmt, 
+			       anim->pCodecCtx->width,
+			       anim->pCodecCtx->height);
 	}
 
 	if (pCodecCtx->has_b_frames) {
@@ -600,11 +604,11 @@
 	}
 	
 	anim->img_convert_ctx = sws_getContext(
-	        anim->pCodecCtx->width,
-	        anim->pCodecCtx->height,
+	        anim->x,
+	        anim->y,
 	        anim->pCodecCtx->pix_fmt,
-	        anim->pCodecCtx->width,
-	        anim->pCodecCtx->height,
+	        anim->x,
+	        anim->y,
 	        PIX_FMT_RGBA,
 	        SWS_FAST_BILINEAR | SWS_PRINT_INFO | SWS_FULL_CHR_H_INT,
 	        NULL, NULL, NULL);
@@ -632,11 +636,11 @@
 		if (sws_setColorspaceDetails(anim->img_convert_ctx, (int *)inv_table, srcRange,
 		                             table, dstRange, brightness, contrast, saturation))
 		{
-			printf("Warning: Could not set libswscale colorspace details.\n");
+			fprintf(stderr, "Warning: Could not set libswscale colorspace details.\n");
 		}
 	}
 	else {
-		printf("Warning: Could not set libswscale colorspace details.\n");
+		fprintf(stderr, "Warning: Could not set libswscale colorspace details.\n");
 	}
 #endif
 		
@@ -709,7 +713,7 @@
 		          (const uint8_t *const *)input->data,
 		          input->linesize,
 		          0,
-		          anim->pCodecCtx->height,
+		          anim->y,
 		          dst2,
 		          dstStride2);
 		
@@ -754,7 +758,7 @@
 		          (const uint8_t *const *)input->data,
 		          input->linesize,
 		          0,
-		          anim->pCodecCtx->height,
+		          anim->y,
 		          dst2,
 		          dstStride2);
 	}
@@ -954,8 +958,8 @@
 	long long st_time; 
 	struct anim_index *tc_index = 0;
 	AVStream *v_st;
-	int new_frame_index = 0; /* To quite gcc barking... */
-	int old_frame_index = 0; /* To quite gcc barking... */
+	int new_frame_index = 0; /* To quiet gcc barking... */
+	int old_frame_index = 0; /* To quiet gcc barking... */
 
 	if (anim == 0) return (0);
 

Modified: trunk/blender/source/blender/imbuf/intern/indexer.c
===================================================================
--- trunk/blender/source/blender/imbuf/intern/indexer.c	2013-04-14 12:01:12 UTC (rev 56045)
+++ trunk/blender/source/blender/imbuf/intern/indexer.c	2013-04-14 13:44:04 UTC (rev 56046)
@@ -552,7 +552,7 @@
 	rv->video_buffer = (uint8_t *)MEM_mallocN(
 	        rv->video_buffersize, "FFMPEG video buffer");
 
-	rv->orig_height = st->codec->height;
+	rv->orig_height = av_get_cropped_height_from_codec(st->codec);
 
 	if (st->codec->width != width || st->codec->height != height ||
 	    st->codec->pix_fmt != rv->c->pix_fmt)
@@ -567,7 +567,7 @@
 
 		rv->sws_ctx = sws_getContext(
 		        st->codec->width,
-		        st->codec->height,
+		        rv->orig_height,
 		        st->codec->pix_fmt,
 		        width, height,
 		        rv->c->pix_fmt,
@@ -809,7 +809,8 @@
 			context->proxy_ctx[i] = alloc_proxy_output_ffmpeg(
 			        anim, context->iStream, proxy_sizes[i],
 			        context->iCodecCtx->width * proxy_fac[i],
-			        context->iCodecCtx->height * proxy_fac[i],
+			        av_get_cropped_height_from_codec(
+					context->iCodecCtx) * proxy_fac[i],
 			        quality);
 			if (!context->proxy_ctx[i]) {
 				proxy_sizes_in_use &= ~proxy_sizes[i];




More information about the Bf-blender-cvs mailing list