Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Schlaile <peter@schlaile.de>2013-04-14 17:44:04 +0400
committerPeter Schlaile <peter@schlaile.de>2013-04-14 17:44:04 +0400
commit1166609cd36af1ab43a1f5004afaac34bcc9d94a (patch)
tree1f8619732e620d78b5a3b1148cbddfdd96b1c0e3
parent456f3b318aa6ce4af2f12844bd89532eabea3374 (diff)
== 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
-rw-r--r--intern/ffmpeg/ffmpeg_compat.h32
-rw-r--r--source/blender/imbuf/intern/anim_movie.c40
-rw-r--r--source/blender/imbuf/intern/indexer.c7
3 files changed, 58 insertions, 21 deletions
diff --git a/intern/ffmpeg/ffmpeg_compat.h b/intern/ffmpeg/ffmpeg_compat.h
index aaedbe2dccd..cd56e3b28d2 100644
--- a/intern/ffmpeg/ffmpeg_compat.h
+++ b/intern/ffmpeg/ffmpeg_compat.h
@@ -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)
diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c
index 8fe98d1de45..d1772229598 100644
--- a/source/blender/imbuf/intern/anim_movie.c
+++ b/source/blender/imbuf/intern/anim_movie.c
@@ -548,7 +548,13 @@ static int startffmpeg(struct anim *anim)
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 @@ static int startffmpeg(struct anim *anim)
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 @@ static int startffmpeg(struct anim *anim)
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 @@ static int startffmpeg(struct anim *anim)
}
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 @@ static int startffmpeg(struct anim *anim)
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 @@ static void ffmpeg_postprocess(struct anim *anim)
(const uint8_t *const *)input->data,
input->linesize,
0,
- anim->pCodecCtx->height,
+ anim->y,
dst2,
dstStride2);
@@ -754,7 +758,7 @@ static void ffmpeg_postprocess(struct anim *anim)
(const uint8_t *const *)input->data,
input->linesize,
0,
- anim->pCodecCtx->height,
+ anim->y,
dst2,
dstStride2);
}
@@ -954,8 +958,8 @@ static ImBuf *ffmpeg_fetchibuf(struct anim *anim, int position,
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);
diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c
index 002ffd409a2..780ca7e5769 100644
--- a/source/blender/imbuf/intern/indexer.c
+++ b/source/blender/imbuf/intern/indexer.c
@@ -552,7 +552,7 @@ static struct proxy_output_ctx *alloc_proxy_output_ffmpeg(
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 @@ static struct proxy_output_ctx *alloc_proxy_output_ffmpeg(
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 @@ static IndexBuildContext *index_ffmpeg_create_context(struct anim *anim, IMB_Tim
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];