#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)
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;
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();
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) {
}
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);
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
(const uint8_t *const *)input->data,
input->linesize,
0,
- anim->pCodecCtx->height,
+ anim->y,
dst2,
dstStride2);
(const uint8_t *const *)input->data,
input->linesize,
0,
- anim->pCodecCtx->height,
+ anim->y,
dst2,
dstStride2);
}
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);
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)
rv->sws_ctx = sws_getContext(
st->codec->width,
- st->codec->height,
+ rv->orig_height,
st->codec->pix_fmt,
width, height,
rv->c->pix_fmt,
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];