The decoder support is unfortunately dismal. --- libavcodec/h264_changesps_bsf.c | 103 +++++++++++++++++++++++++--------------- 1 file changed, 64 insertions(+), 39 deletions(-)
diff --git a/libavcodec/h264_changesps_bsf.c b/libavcodec/h264_changesps_bsf.c index 43e0d62..39896fa 100644 --- a/libavcodec/h264_changesps_bsf.c +++ b/libavcodec/h264_changesps_bsf.c @@ -1,6 +1,7 @@ /* * H.264 change sps filter * Copyright (c) 2010 Zongyi Zhou <zho...@os.pku.edu.cn> + * Copyright (c) 2014 Christophe Gisquet <christophe.gisq...@gmail.com> * * This file is part of FFmpeg. * @@ -35,15 +36,16 @@ typedef struct H264SPSContext { int32_t refs; uint32_t remove_nal_flags, delay_remove_flags; int16_t sar_x, sar_y; - int16_t crop_x, crop_y; + int16_t crop[4]; int8_t fullrange, colorprim, transfer, colmatrix; } H264SPSContext; static int parse_args(struct H264SPSContext *c, const char *args) { int r = 0; - int32_t sarx = -1, sary = -1, cropx = -1, cropy = -1, level = -1, + int32_t sarx = -1, sary = -1, level = -1, refs = -1, colorprim = -1, transfer = -1, colmatrix = -1; + int32_t cropl = -1, cropt = -1, cropr = -1, cropb = -1; if (!args) return 0; c->fps_den = c->fps_num = c->fps_mode = -1; c->fullrange = -1; @@ -51,13 +53,15 @@ static int parse_args(struct H264SPSContext *c, const char *args) while (*args) { if (sscanf(args, "fps=%u:%u", &c->fps_num, &c->fps_den) == 2 || sscanf(args, "sar=%u:%u", &sarx, &sary) == 2 || - sscanf(args, "crop=%u:%u", &cropx, &cropy) == 2 || sscanf(args, "level=%u", &level) == 1 || sscanf(args, "ref=%u", &refs) == 1 || sscanf(args, "colorprim=%u", &colorprim) == 1 || sscanf(args, "transfer=%u", &transfer) == 1 || sscanf(args, "colormatrix=%u", &colmatrix) == 1) r++; + else if (sscanf(args, "crop=%u:%u:%u:%u", + &cropl, &cropt, &cropr, &cropb) == 4) + r++; else if (!strncmp(args, "vfr", 3)) { r++; c->fps_mode = 0; @@ -84,9 +88,11 @@ static int parse_args(struct H264SPSContext *c, const char *args) args++; } if (sary == -1) sarx = -1; - if (cropy == -1) cropx = -1; + if (cropt == -1) cropl = -1; + if (cropb == -1) cropr = -1; c->sar_x = sarx; c->sar_y = sary; - c->crop_x = cropx; c->crop_y = cropy; + c->crop[0] = cropl; c->crop[1] = cropr; + c->crop[2] = cropt; c->crop[3] = cropb; c->level = level; c->refs = refs; c->colorprim = colorprim; @@ -172,7 +178,9 @@ static int h264_modify(uint8_t *outbuf, const uint8_t *inbuf, H264SPSContext *ct #define COPYUE31 set_ue_golomb(&pb, get_ue_golomb_31(&gb)) #define COPYSE set_se_golomb(&pb, get_se_golomb(&gb)) #define COPYBITS1 put_bits(&pb, 1, get_bits1(&gb)) - int p, t, i; + int p, t, i, frame_mbs_only, mb_width, mb_height; + int chroma_format_idc = 1; // default value for non-High profile + int csub[2]; init_get_bits(&gb, inbuf, insize * 8); init_put_bits(&pb, outbuf, (insize + 10) * 8); p = get_bits(&gb, 8); //profile_idc @@ -184,9 +192,9 @@ static int h264_modify(uint8_t *outbuf, const uint8_t *inbuf, H264SPSContext *ct put_bits(&pb, 8, t); COPYUE31; if (p >= 100) { - t = get_ue_golomb(&gb); //chroma_format_idc - set_ue_golomb(&pb, t); - if (t == 3) + chroma_format_idc = get_ue_golomb(&gb); + set_ue_golomb(&pb, chroma_format_idc); + if (chroma_format_idc == 3) COPYBITS1; //residue_transform_flag COPYUE; //bit_depth_luma_minus8 COPYUE; //bit_depth_chroma_minus8 @@ -221,38 +229,49 @@ static int h264_modify(uint8_t *outbuf, const uint8_t *inbuf, H264SPSContext *ct t = ctx->refs; set_ue_golomb(&pb,t); COPYBITS1; - COPYUE; - COPYUE; - i = get_bits1(&gb); //frame_mbs_only - put_bits(&pb, 1, i); - if (!i) COPYBITS1; + mb_width = get_ue_golomb(&gb); + mb_height = get_ue_golomb(&gb); + set_ue_golomb(&pb,mb_width); + set_ue_golomb(&pb,mb_height); + frame_mbs_only = get_bits1(&gb); + put_bits(&pb, 1, frame_mbs_only); + if (!frame_mbs_only) COPYBITS1; COPYBITS1; + csub[0] = (chroma_format_idc == 1 || chroma_format_idc == 2) ? 1 : 0; + csub[1] = (chroma_format_idc == 1) ? 1 : 0; + csub[1] += 1-frame_mbs_only; t = get_bits1(&gb); - if (ctx->crop_x == -1) - put_bits(&pb, 1, t); if (t) { - int t1, t2, t3, t4; - t1 = get_ue_golomb(&gb), - t2 = get_ue_golomb(&gb), - t3 = get_ue_golomb(&gb), - t4 = get_ue_golomb(&gb); - if (ctx->crop_x == -1) { - set_ue_golomb(&pb, t1); - set_ue_golomb(&pb, t2); - set_ue_golomb(&pb, t3); - set_ue_golomb(&pb, t4); + for (i=0; i<4; i++) { + int val = get_ue_golomb(&gb); + if (ctx->crop[i] < 0) + ctx->crop[i] = val << csub[i>>1]; } } - if (ctx->crop_x != -1) { - if (ctx->crop_x || ctx->crop_y) { - put_bits(&pb, 1, 1); - set_ue_golomb(&pb, 0); - set_ue_golomb(&pb, (ctx->crop_x + 1) >> 1); - set_ue_golomb(&pb, 0); - set_ue_golomb(&pb, (ctx->crop_y + 1) >> (2 >> i)); - } else put_bits(&pb, 1, 0); - } + if (ctx->crop[0] >= 0 || ctx->crop[1] >= 0 || + ctx->crop[2] >= 0 || ctx->crop[3] >= 0) { + static const char* names[4] = { "left", "right", "top", "bottom" }; + int dim[2] = { 16 * mb_width, 16 * mb_height * (2 - frame_mbs_only) }; + + put_bits(&pb, 1, 1); + + for (i=0; i<4; i++) { + int s = csub[i>>1], d = dim[i>>1]; + int crop = ctx->crop[i] < 0 ? 0 : (ctx->crop[i] & -1L <<s); + if (crop >= d || (i&1 && crop+ctx->crop[i-1] >= d)) { + av_log(ctx, AV_LOG_WARNING, "Invalid %s crop value %d / %d\n", + names[i], ctx->crop[i], d); + crop = 0; + } else if (crop != ctx->crop[i]) + av_log(ctx, AV_LOG_WARNING, "Changed %s crop from %d to %d\n", + names[i], ctx->crop[i], crop); + set_ue_golomb(&pb, crop>>s); + ctx->crop[i] = crop; + } + } else + put_bits(&pb, 1, 0); + t = get_bits1(&gb); put_bits(&pb, 1, t); if (t) { @@ -470,10 +489,16 @@ static int h264_changesps_filter(AVBitStreamFilterContext *bsfc, ndata[3] = ctx->level; m = (ndata[5] & 0x1f)? 6 : 7; AV_WB16(ndata + m, AV_RB16(ndata + m) + d); - if (ctx->crop_x != -1) { - avctx->width = ((avctx->width + 15) & ~15) - ctx->crop_x; - avctx->height = ((avctx->height + 15) & ~15) - ctx->crop_y; - } + d = ctx->crop[0] < 0 ? 0 : ctx->crop[0]; + if (ctx->crop[1] > 0) + d += ctx->crop[1]; + if (d > 0) + avctx->width = ((avctx->width + 15) & ~15) - d; + d = ctx->crop[2] < 0 ? 0 : ctx->crop[2]; + if (ctx->crop[3] > 0) + d += ctx->crop[3]; + if (d > 0) + avctx->height = ((avctx->height + 15) & ~15) - d; r = ctx->fps_num; if (r > 0) { avctx->time_base.den = r; -- 1.9.2.msysgit.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel