X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fvp6.c;h=d10a64001aed0f2955215937dc6d8c47333e7193;hb=13e4f2c7f7857feb6885f0c2ea8c9ddf438f46ea;hp=c3428fef5fab9c338cd567a2f4f07502fd40be42;hpb=be75fed9755c1285ba084574aff2d7ee0f81110d;p=ffmpeg diff --git a/libavcodec/vp6.c b/libavcodec/vp6.c index c3428fef5fa..d10a64001ae 100644 --- a/libavcodec/vp6.c +++ b/libavcodec/vp6.c @@ -30,9 +30,9 @@ #include #include "avcodec.h" -#include "dsputil.h" #include "get_bits.h" #include "huffman.h" +#include "internal.h" #include "vp56.h" #include "vp56data.h" @@ -52,19 +52,19 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, int vrt_shift = 0; int sub_version; int rows, cols; - int res = 1; + int res = 0; int separated_coeff = buf[0] & 1; - s->framep[VP56_FRAME_CURRENT]->key_frame = !(buf[0] & 0x80); + s->frames[VP56_FRAME_CURRENT]->key_frame = !(buf[0] & 0x80); ff_vp56_init_dequant(s, (buf[0] >> 1) & 0x3F); - if (s->framep[VP56_FRAME_CURRENT]->key_frame) { + if (s->frames[VP56_FRAME_CURRENT]->key_frame) { sub_version = buf[1] >> 3; if (sub_version > 8) - return 0; + return AVERROR_INVALIDDATA; s->filter_header = buf[1] & 0x06; if (buf[1] & 1) { - av_log_missing_feature(s->avctx, "Interlacing", 0); + avpriv_report_missing_feature(s->avctx, "Interlacing"); return AVERROR_PATCHWELCOME; } if (separated_coeff || !s->filter_header) { @@ -79,18 +79,31 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, /* buf[5] is number of displayed macroblock cols */ if (!rows || !cols) { av_log(s->avctx, AV_LOG_ERROR, "Invalid size %dx%d\n", cols << 4, rows << 4); - return 0; + return AVERROR_INVALIDDATA; } if (!s->macroblocks || /* first frame */ 16*cols != s->avctx->coded_width || 16*rows != s->avctx->coded_height) { - avcodec_set_dimensions(s->avctx, 16*cols, 16*rows); - if (s->avctx->extradata_size == 1) { - s->avctx->width -= s->avctx->extradata[0] >> 4; - s->avctx->height -= s->avctx->extradata[0] & 0x0F; + if (s->avctx->extradata_size == 0 && + FFALIGN(s->avctx->width, 16) == 16 * cols && + FFALIGN(s->avctx->height, 16) == 16 * rows) { + // We assume this is properly signalled container cropping, + // in an F4V file. Just set the coded_width/height, don't + // touch the cropped ones. + s->avctx->coded_width = 16 * cols; + s->avctx->coded_height = 16 * rows; + } else { + int ret = ff_set_dimensions(s->avctx, 16 * cols, 16 * rows); + if (ret < 0) + return ret; + + if (s->avctx->extradata_size == 1) { + s->avctx->width -= s->avctx->extradata[0] >> 4; + s->avctx->height -= s->avctx->extradata[0] & 0x0F; + } } - res = 2; + res = VP56_SIZE_CHANGE; } ff_vp56_init_range_decoder(c, buf+6, buf_size-6); @@ -102,7 +115,7 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, s->sub_version = sub_version; } else { if (!s->sub_version || !s->avctx->coded_width || !s->avctx->coded_height) - return 0; + return AVERROR_INVALIDDATA; if (separated_coeff || !s->filter_header) { coeff_offset = AV_RB16(buf+1) - 2; @@ -144,9 +157,9 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, buf += coeff_offset; buf_size -= coeff_offset; if (buf_size < 0) { - if (s->framep[VP56_FRAME_CURRENT]->key_frame) - avcodec_set_dimensions(s->avctx, 0, 0); - return 0; + if (s->frames[VP56_FRAME_CURRENT]->key_frame) + ff_set_dimensions(s->avctx, 0, 0); + return AVERROR_INVALIDDATA; } if (s->use_huffman) { s->parse_coeff = vp6_parse_coeff_huffman; @@ -259,7 +272,7 @@ static int vp6_parse_coeff_models(VP56Context *s) if (vp56_rac_get_prob(c, vp6_dccv_pct[pt][node])) { def_prob[node] = vp56_rac_gets_nn(c, 7); model->coeff_dccv[pt][node] = def_prob[node]; - } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) { + } else if (s->frames[VP56_FRAME_CURRENT]->key_frame) { model->coeff_dccv[pt][node] = def_prob[node]; } @@ -282,7 +295,7 @@ static int vp6_parse_coeff_models(VP56Context *s) if (vp56_rac_get_prob(c, vp6_ract_pct[ct][pt][cg][node])) { def_prob[node] = vp56_rac_gets_nn(c, 7); model->coeff_ract[pt][ct][cg][node] = def_prob[node]; - } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) { + } else if (s->frames[VP56_FRAME_CURRENT]->key_frame) { model->coeff_ract[pt][ct][cg][node] = def_prob[node]; } @@ -369,7 +382,7 @@ static unsigned vp6_get_nb_null(VP56Context *s) static void vp6_parse_coeff_huffman(VP56Context *s) { VP56Model *model = s->modelp; - uint8_t *permute = s->scantable.permutated; + uint8_t *permute = s->idct_scantable; VLC *vlc_coeff; int coeff, sign, coeff_idx; int b, cg, idx; @@ -429,7 +442,7 @@ static void vp6_parse_coeff(VP56Context *s) { VP56RangeCoder *c = s->ccp; VP56Model *model = s->modelp; - uint8_t *permute = s->scantable.permutated; + uint8_t *permute = s->idct_scantable; uint8_t *model1, *model2, *model3; int coeff, sign, coeff_idx; int b, i, cg, idx, ctx; @@ -536,8 +549,8 @@ static void vp6_filter_diag2(VP56Context *s, uint8_t *dst, uint8_t *src, int stride, int h_weight, int v_weight) { uint8_t *tmp = s->edge_emu_buffer+16; - s->dsp.put_h264_chroma_pixels_tab[0](tmp, src, stride, 9, h_weight, 0); - s->dsp.put_h264_chroma_pixels_tab[0](dst, tmp, stride, 8, 0, v_weight); + s->h264chroma.put_h264_chroma_pixels_tab[0](tmp, src, stride, 9, h_weight, 0); + s->h264chroma.put_h264_chroma_pixels_tab[0](dst, tmp, stride, 8, 0, v_weight); } static void vp6_filter(VP56Context *s, uint8_t *dst, uint8_t *src, @@ -583,7 +596,7 @@ static void vp6_filter(VP56Context *s, uint8_t *dst, uint8_t *src, } } else { if (!x8 || !y8) { - s->dsp.put_h264_chroma_pixels_tab[0](dst, src+offset1, stride, 8, x8, y8); + s->h264chroma.put_h264_chroma_pixels_tab[0](dst, src + offset1, stride, 8, x8, y8); } else { vp6_filter_diag2(s, dst, src+offset1 + ((mv.x^mv.y)>>31), stride, x8, y8); } @@ -593,9 +606,12 @@ static void vp6_filter(VP56Context *s, uint8_t *dst, uint8_t *src, static av_cold int vp6_decode_init(AVCodecContext *avctx) { VP56Context *s = avctx->priv_data; + int ret; + + if ((ret = ff_vp56_init(avctx, avctx->codec->id == AV_CODEC_ID_VP6, + avctx->codec->id == AV_CODEC_ID_VP6A)) < 0) + return ret; - ff_vp56_init(avctx, avctx->codec->id == AV_CODEC_ID_VP6, - avctx->codec->id == AV_CODEC_ID_VP6A); s->vp56_coord_div = vp6_coord_div; s->parse_vector_adjustment = vp6_parse_vector_adjustment; s->filter = vp6_filter; @@ -626,6 +642,7 @@ static av_cold int vp6_decode_free(AVCodecContext *avctx) AVCodec ff_vp6_decoder = { .name = "vp6", + .long_name = NULL_IF_CONFIG_SMALL("On2 VP6"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_VP6, .priv_data_size = sizeof(VP56Context), @@ -633,12 +650,12 @@ AVCodec ff_vp6_decoder = { .close = vp6_decode_free, .decode = ff_vp56_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("On2 VP6"), }; /* flash version, not flipped upside-down */ AVCodec ff_vp6f_decoder = { .name = "vp6f", + .long_name = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_VP6F, .priv_data_size = sizeof(VP56Context), @@ -646,12 +663,12 @@ AVCodec ff_vp6f_decoder = { .close = vp6_decode_free, .decode = ff_vp56_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version)"), }; /* flash version, not flipped upside-down, with alpha channel */ AVCodec ff_vp6a_decoder = { .name = "vp6a", + .long_name = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version, with alpha channel)"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_VP6A, .priv_data_size = sizeof(VP56Context), @@ -659,5 +676,4 @@ AVCodec ff_vp6a_decoder = { .close = vp6_decode_free, .decode = ff_vp56_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version, with alpha channel)"), };