X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=libavcodec%2Fffv1dec.c;h=261e0cf70c239a966206c6bc6b2a2bea48c05631;hb=c71e1e60305669c225c696dd99f6db5dc550a56a;hp=5eadb6b158648c4ae796fd37617c6e94e5ff87dd;hpb=980af9a88cfd743d71fad67e7dd905231ea0a4f7;p=ffmpeg diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c index 5eadb6b1586..261e0cf70c2 100644 --- a/libavcodec/ffv1dec.c +++ b/libavcodec/ffv1dec.c @@ -336,14 +336,16 @@ static int decode_slice(AVCodecContext *c, void *arg) decode_plane(fs, p->data[0] + ps*x + y*p->linesize[0] , width, height, p->linesize[0], 0, 2); decode_plane(fs, p->data[0] + ps*x + y*p->linesize[0] + 1, width, height, p->linesize[0], 1, 2); } else if (f->use32bit) { - uint8_t *planes[3] = { p->data[0] + ps * x + y * p->linesize[0], + uint8_t *planes[4] = { p->data[0] + ps * x + y * p->linesize[0], p->data[1] + ps * x + y * p->linesize[1], - p->data[2] + ps * x + y * p->linesize[2] }; + p->data[2] + ps * x + y * p->linesize[2], + p->data[3] + ps * x + y * p->linesize[3] }; decode_rgb_frame32(fs, planes, width, height, p->linesize); } else { - uint8_t *planes[3] = { p->data[0] + ps * x + y * p->linesize[0], + uint8_t *planes[4] = { p->data[0] + ps * x + y * p->linesize[0], p->data[1] + ps * x + y * p->linesize[1], - p->data[2] + ps * x + y * p->linesize[2] }; + p->data[2] + ps * x + y * p->linesize[2], + p->data[3] + ps * x + y * p->linesize[3] }; decode_rgb_frame(fs, planes, width, height, p->linesize); } if (fs->ac != AC_GOLOMB_RICE && f->version > 2) { @@ -544,8 +546,14 @@ static int read_header(FFV1Context *f) f->ac = get_symbol(c, state, 0); if (f->ac == AC_RANGE_CUSTOM_TAB) { - for (i = 1; i < 256; i++) - f->state_transition[i] = get_symbol(c, state, 1) + c->one_state[i]; + for (i = 1; i < 256; i++) { + int st = get_symbol(c, state, 1) + c->one_state[i]; + if (st < 1 || st > 255) { + av_log(f->avctx, AV_LOG_ERROR, "invalid state transition %d\n", st); + return AVERROR_INVALIDDATA; + } + f->state_transition[i] = st; + } } colorspace = get_symbol(c, state, 0); //YUV cs type @@ -589,7 +597,10 @@ static int read_header(FFV1Context *f) if (!f->transparency && !f->chroma_planes) { if (f->avctx->bits_per_raw_sample <= 8) f->avctx->pix_fmt = AV_PIX_FMT_GRAY8; - else if (f->avctx->bits_per_raw_sample == 10) { + else if (f->avctx->bits_per_raw_sample == 9) { + f->packed_at_lsb = 1; + f->avctx->pix_fmt = AV_PIX_FMT_GRAY9; + } else if (f->avctx->bits_per_raw_sample == 10) { f->packed_at_lsb = 1; f->avctx->pix_fmt = AV_PIX_FMT_GRAY10; } else if (f->avctx->bits_per_raw_sample == 12) { @@ -640,6 +651,7 @@ static int read_header(FFV1Context *f) f->packed_at_lsb = 1; switch(16 * f->chroma_h_shift + f->chroma_v_shift) { case 0x00: f->avctx->pix_fmt = AV_PIX_FMT_YUV444P10; break; + case 0x01: f->avctx->pix_fmt = AV_PIX_FMT_YUV440P10; break; case 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUV422P10; break; case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUV420P10; break; } @@ -654,9 +666,17 @@ static int read_header(FFV1Context *f) f->packed_at_lsb = 1; switch(16 * f->chroma_h_shift + f->chroma_v_shift) { case 0x00: f->avctx->pix_fmt = AV_PIX_FMT_YUV444P12; break; + case 0x01: f->avctx->pix_fmt = AV_PIX_FMT_YUV440P12; break; case 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUV422P12; break; case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUV420P12; break; } + } else if (f->avctx->bits_per_raw_sample == 14 && !f->transparency) { + f->packed_at_lsb = 1; + switch(16 * f->chroma_h_shift + f->chroma_v_shift) { + case 0x00: f->avctx->pix_fmt = AV_PIX_FMT_YUV444P14; break; + case 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUV422P14; break; + case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUV420P14; break; + } } else if (f->avctx->bits_per_raw_sample == 16 && !f->transparency){ f->packed_at_lsb = 1; switch(16 * f->chroma_h_shift + f->chroma_v_shift) { @@ -686,14 +706,22 @@ static int read_header(FFV1Context *f) f->avctx->pix_fmt = AV_PIX_FMT_GBRP9; else if (f->avctx->bits_per_raw_sample == 10 && !f->transparency) f->avctx->pix_fmt = AV_PIX_FMT_GBRP10; + else if (f->avctx->bits_per_raw_sample == 10 && f->transparency) + f->avctx->pix_fmt = AV_PIX_FMT_GBRAP10; else if (f->avctx->bits_per_raw_sample == 12 && !f->transparency) f->avctx->pix_fmt = AV_PIX_FMT_GBRP12; + else if (f->avctx->bits_per_raw_sample == 12 && f->transparency) + f->avctx->pix_fmt = AV_PIX_FMT_GBRAP12; else if (f->avctx->bits_per_raw_sample == 14 && !f->transparency) f->avctx->pix_fmt = AV_PIX_FMT_GBRP14; else if (f->avctx->bits_per_raw_sample == 16 && !f->transparency) { f->avctx->pix_fmt = AV_PIX_FMT_GBRP16; f->use32bit = 1; } + else if (f->avctx->bits_per_raw_sample == 16 && f->transparency) { + f->avctx->pix_fmt = AV_PIX_FMT_GBRAP16; + f->use32bit = 1; + } } else { av_log(f->avctx, AV_LOG_ERROR, "colorspace not supported\n"); return AVERROR(ENOSYS); @@ -928,7 +956,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac } if (desc->flags & AV_PIX_FMT_FLAG_PAL || - desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) { + desc->flags & FF_PSEUDOPAL) { dst[1] = p->data[1]; src[1] = f->last_picture.f->data[1]; }