Merge commit '4a2a4524a3f50ed302820ba971ddd48e78c7436f'
authorMichael Niedermayer <michaelni@gmx.at>
Sun, 21 Oct 2012 12:54:16 +0000 (14:54 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Sun, 21 Oct 2012 12:55:21 +0000 (14:55 +0200)
* commit '4a2a4524a3f50ed302820ba971ddd48e78c7436f':
  ffv1: propagate errors

Conflicts:
libavcodec/ffv1dec.c
libavcodec/ffv1enc.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavcodec/ffv1dec.c
libavcodec/ffv1enc.c

@@@ -400,10 -288,10 +400,10 @@@ static int read_quant_table(RangeCoder 
      memset(state, 128, sizeof(state));
  
      for (v = 0; i < 128; v++) {
 -        int len = get_symbol(c, state, 0) + 1;
 +        unsigned len = get_symbol(c, state, 0) + 1;
  
 -        if (len + i > 128)
 +        if (len > 128 - i)
-             return -1;
+             return AVERROR_INVALIDDATA;
  
          while (len--) {
              quant_table[i] = scale * v;
@@@ -543,82 -407,53 +543,82 @@@ static int read_header(FFV1Context *f
      }
  
      if (f->colorspace == 0) {
 -        if (f->avctx->bits_per_raw_sample <= 8) {
 -            switch (16 * f->chroma_h_shift + f->chroma_v_shift) {
 -            case 0x00:
 -                f->avctx->pix_fmt = AV_PIX_FMT_YUV444P;
 -                break;
 -            case 0x10:
 -                f->avctx->pix_fmt = AV_PIX_FMT_YUV422P;
 -                break;
 -            case 0x11:
 -                f->avctx->pix_fmt = AV_PIX_FMT_YUV420P;
 -                break;
 -            case 0x20:
 -                f->avctx->pix_fmt = AV_PIX_FMT_YUV411P;
 -                break;
 -            case 0x22:
 -                f->avctx->pix_fmt = AV_PIX_FMT_YUV410P;
 -                break;
 +        if (!f->transparency && !f->chroma_planes) {
 +            if (f->avctx->bits_per_raw_sample <= 8)
 +                f->avctx->pix_fmt = AV_PIX_FMT_GRAY8;
 +            else
 +                f->avctx->pix_fmt = AV_PIX_FMT_GRAY16;
 +        } else if (f->avctx->bits_per_raw_sample<=8 && !f->transparency) {
 +            switch(16 * f->chroma_h_shift + f->chroma_v_shift) {
 +            case 0x00: f->avctx->pix_fmt = AV_PIX_FMT_YUV444P; break;
 +            case 0x01: f->avctx->pix_fmt = AV_PIX_FMT_YUV440P; break;
 +            case 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUV422P; break;
 +            case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUV420P; break;
 +            case 0x20: f->avctx->pix_fmt = AV_PIX_FMT_YUV411P; break;
 +            case 0x22: f->avctx->pix_fmt = AV_PIX_FMT_YUV410P; break;
 +            default:
 +                av_log(f->avctx, AV_LOG_ERROR, "format not supported\n");
 +                return -1;
 +            }
 +        } else if (f->avctx->bits_per_raw_sample <= 8 && f->transparency) {
 +            switch(16*f->chroma_h_shift + f->chroma_v_shift) {
 +            case 0x00: f->avctx->pix_fmt = AV_PIX_FMT_YUVA444P; break;
 +            case 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUVA422P; break;
 +            case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUVA420P; break;
 +            default:
 +                av_log(f->avctx, AV_LOG_ERROR, "format not supported\n");
 +                return -1;
 +            }
 +        } else if (f->avctx->bits_per_raw_sample == 9) {
 +            f->packed_at_lsb = 1;
 +            switch(16 * f->chroma_h_shift + f->chroma_v_shift) {
 +            case 0x00: f->avctx->pix_fmt = AV_PIX_FMT_YUV444P9; break;
 +            case 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUV422P9; break;
 +            case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUV420P9; break;
 +            default:
 +                av_log(f->avctx, AV_LOG_ERROR, "format not supported\n");
 +                return -1;
 +            }
 +        } else if (f->avctx->bits_per_raw_sample == 10) {
 +            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 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUV422P10; break;
 +            case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUV420P10; break;
              default:
                  av_log(f->avctx, AV_LOG_ERROR, "format not supported\n");
-                 return -1;
+                 return AVERROR(ENOSYS);
              }
          } else {
 -            switch (16 * f->chroma_h_shift + f->chroma_v_shift) {
 -            case 0x00:
 -                f->avctx->pix_fmt = AV_PIX_FMT_YUV444P16;
 -                break;
 -            case 0x10:
 -                f->avctx->pix_fmt = AV_PIX_FMT_YUV422P16;
 -                break;
 -            case 0x11:
 -                f->avctx->pix_fmt = AV_PIX_FMT_YUV420P16;
 -                break;
 +            switch(16 * f->chroma_h_shift + f->chroma_v_shift) {
 +            case 0x00: f->avctx->pix_fmt = AV_PIX_FMT_YUV444P16; break;
 +            case 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUV422P16; break;
 +            case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUV420P16; break;
              default:
                  av_log(f->avctx, AV_LOG_ERROR, "format not supported\n");
-                 return -1;
+                 return AVERROR(ENOSYS);
              }
          }
      } else if (f->colorspace == 1) {
          if (f->chroma_h_shift || f->chroma_v_shift) {
              av_log(f->avctx, AV_LOG_ERROR,
                     "chroma subsampling not supported in this colorspace\n");
-             return -1;
+             return AVERROR(ENOSYS);
          }
 -        f->avctx->pix_fmt = AV_PIX_FMT_RGB32;
 +        if (     f->avctx->bits_per_raw_sample ==  9)
 +            f->avctx->pix_fmt = AV_PIX_FMT_GBRP9;
 +        else if (f->avctx->bits_per_raw_sample == 10)
 +            f->avctx->pix_fmt = AV_PIX_FMT_GBRP10;
 +        else if (f->avctx->bits_per_raw_sample == 12)
 +            f->avctx->pix_fmt = AV_PIX_FMT_GBRP12;
 +        else if (f->avctx->bits_per_raw_sample == 14)
 +            f->avctx->pix_fmt = AV_PIX_FMT_GBRP14;
 +        else
 +        if (f->transparency) f->avctx->pix_fmt = AV_PIX_FMT_RGB32;
 +        else                 f->avctx->pix_fmt = AV_PIX_FMT_0RGB32;
      } else {
          av_log(f->avctx, AV_LOG_ERROR, "colorspace not supported\n");
-         return -1;
+         return AVERROR(ENOSYS);
      }
  
      av_dlog(f->avctx, "%d %d %d\n",
          context_count = read_quant_tables(c, f->quant_table);
          if (context_count < 0) {
              av_log(f->avctx, AV_LOG_ERROR, "read_quant_table error\n");
-             return -1;
+             return context_count;
          }
 -    } else {
 +    } else if (f->version < 3) {
          f->slice_count = get_symbol(c, state, 0);
 -        if (f->slice_count > (unsigned)MAX_SLICES)
 -            return AVERROR_INVALIDDATA;
 +    } else {
 +        const uint8_t *p = c->bytestream_end;
 +        for (f->slice_count = 0; f->slice_count < MAX_SLICES && 3 < p - c->bytestream_start; f->slice_count++) {
 +            int trailer = 3 + 5*!!f->ec;
 +            int size = AV_RB24(p-trailer);
 +            if (size + trailer > p - c->bytestream_start)
 +                break;
 +            p -= size + trailer;
 +        }
 +    }
 +    if (f->slice_count > (unsigned)MAX_SLICES || f->slice_count <= 0) {
 +        av_log(f->avctx, AV_LOG_ERROR, "slice count %d is invalid\n", f->slice_count);
-         return -1;
++        return AVERROR_INVALIDDATA;
      }
  
      for (j = 0; j < f->slice_count; j++) {
      return 0;
  }
  
 -static av_cold int ffv1_decode_init(AVCodecContext *avctx)
 +static av_cold int decode_init(AVCodecContext *avctx)
  {
      FFV1Context *f = avctx->priv_data;
+     int ret;
  
      ffv1_common_init(avctx);
  
@@@ -725,7 -546,7 +726,7 @@@ static int decode_frame(AVCodecContext 
      FFV1Context *f      = avctx->priv_data;
      RangeCoder *const c = &f->slice_context[0]->c;
      AVFrame *const p    = &f->picture;
-     int i;
 -    int bytes_read, i, ret;
++    int i, ret;
      uint8_t keystate = 128;
      const uint8_t *buf_p;
  
      p->pict_type = AV_PICTURE_TYPE_I; // FIXME: I vs. P
      if (get_rac(c, &keystate)) {
          p->key_frame = 1;
-         if (read_header(f) < 0)
-             return -1;
 +        f->key_frame_ok = 0;
 -        if ((ret = ffv1_init_slice_state(f)) < 0)
 -            return ret;
 -
 -        ffv1_clear_state(f);
+         if ((ret = read_header(f)) < 0)
+             return ret;
 +        f->key_frame_ok = 1;
      } else {
 -        p->key_frame = 0;
 -    }
 -    if (f->ac > 1) {
 -        int i;
 -        for (i = 1; i < 256; i++) {
 -            c->one_state[i]        = f->state_transition[i];
 -            c->zero_state[256 - i] = 256 - c->one_state[i];
 +        if (!f->key_frame_ok) {
 +            av_log(avctx, AV_LOG_ERROR, "Cant decode non keyframe without valid keyframe\n");
 +            return AVERROR_INVALIDDATA;
          }
 +        p->key_frame= 0;
      }
  
 -    p->reference = 0;
 +    p->reference = 3; //for error concealment
-     if (avctx->get_buffer(avctx, p) < 0) {
+     if ((ret = avctx->get_buffer(avctx, p)) < 0) {
          av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-         return -1;
+         return ret;
      }
  
 -    if (avctx->debug & FF_DEBUG_PICT_INFO)
 -        av_log(avctx, AV_LOG_ERROR, "keyframe:%d coder:%d\n", p->key_frame, f->ac);
 -
 -    if (!f->ac) {
 -        bytes_read = c->bytestream - c->bytestream_start - 1;
 -        if (bytes_read == 0)
 -            av_log(avctx, AV_LOG_ERROR, "error at end of AC stream\n"); // FIXME
 -        init_get_bits(&f->slice_context[0]->gb, buf + bytes_read,
 -                      (buf_size - bytes_read) * 8);
 -    } else {
 -        bytes_read = 0; /* avoid warning */
 -    }
 +    if (avctx->debug&FF_DEBUG_PICT_INFO)
 +        av_log(avctx, AV_LOG_DEBUG, "ver:%d keyframe:%d coder:%d ec:%d slices:%d bps:%d\n",
 +               f->version, p->key_frame, f->ac, f->ec, f->slice_count, f->avctx->bits_per_raw_sample);
  
      buf_p = buf + buf_size;
 -    for (i = f->slice_count - 1; i > 0; i--) {
 +    for (i = f->slice_count - 1; i >= 0; i--) {
          FFV1Context *fs = f->slice_context[i];
 -        int v           = AV_RB24(buf_p - 3) + 3;
 -        if (buf_p - buf <= v) {
 +        int trailer = 3 + 5*!!f->ec;
 +        int v;
 +
 +        if (i || f->version>2) v = AV_RB24(buf_p-trailer)+trailer;
 +        else                   v = buf_p - c->bytestream_start;
 +        if (buf_p - c->bytestream_start < v) {
              av_log(avctx, AV_LOG_ERROR, "Slice pointer chain broken\n");
-             return -1;
+             return AVERROR_INVALIDDATA;
          }
          buf_p -= v;
 -        if (fs->ac)
 +
 +        if (f->ec) {
 +            unsigned crc = av_crc(av_crc_get_table(AV_CRC_32_IEEE), 0, buf_p, v);
 +            if (crc) {
 +                int64_t ts = avpkt->pts != AV_NOPTS_VALUE ? avpkt->pts : avpkt->dts;
 +                av_log(f->avctx, AV_LOG_ERROR, "CRC mismatch %X!", crc);
 +                if (ts != AV_NOPTS_VALUE && avctx->pkt_timebase.num) {
 +                    av_log(f->avctx, AV_LOG_ERROR, "at %f seconds\n", ts*av_q2d(avctx->pkt_timebase));
 +                } else if (ts != AV_NOPTS_VALUE) {
 +                    av_log(f->avctx, AV_LOG_ERROR, "at %"PRId64"\n", ts);
 +                } else {
 +                    av_log(f->avctx, AV_LOG_ERROR, "\n");
 +                }
 +                fs->slice_damaged = 1;
 +            }
 +        }
 +
 +        if (i) {
              ff_init_range_decoder(&fs->c, buf_p, v);
 -        else
 -            init_get_bits(&fs->gb, buf_p, v * 8);
 +        } else
 +            fs->c.bytestream_end = (uint8_t *)(buf_p + v);
 +    }
 +
 +    avctx->execute(avctx, decode_slice, &f->slice_context[0], NULL, f->slice_count, sizeof(void*));
 +
 +    for (i=f->slice_count-1; i>=0; i--) {
 +        FFV1Context *fs= f->slice_context[i];
 +        int j;
 +        if (fs->slice_damaged && f->last_picture.data[0]) {
 +            uint8_t *dst[4], *src[4];
 +            for (j=0; j<4; j++) {
 +                int sh = (j==1 || j==2) ? f->chroma_h_shift : 0;
 +                int sv = (j==1 || j==2) ? f->chroma_v_shift : 0;
 +                dst[j] = f->picture     .data[j] + f->picture     .linesize[j]*
 +                         (fs->slice_y>>sv) + (fs->slice_x>>sh);
 +                src[j] = f->last_picture.data[j] + f->last_picture.linesize[j]*
 +                         (fs->slice_y>>sv) + (fs->slice_x>>sh);
 +            }
 +            av_image_copy(dst, f->picture.linesize, (const uint8_t **)src, f->last_picture.linesize,
 +                          avctx->pix_fmt, fs->slice_width, fs->slice_height);
 +        }
      }
  
 -    avctx->execute(avctx, decode_slice, &f->slice_context[0],
 -                   NULL, f->slice_count, sizeof(void *));
      f->picture_number++;
  
      *picture   = *p;
@@@ -629,11 -496,10 +629,11 @@@ static int sort_stt(FFV1Context *s, uin
      return print;
  }
  
 -static av_cold int ffv1_encode_init(AVCodecContext *avctx)
 +static av_cold int encode_init(AVCodecContext *avctx)
  {
 +    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
      FFV1Context *s = avctx->priv_data;
-     int i, j, k, m;
+     int i, j, k, m, ret;
  
      ffv1_common_init(avctx);
  
              av_log(avctx, AV_LOG_ERROR, "bits_per_raw_sample invalid\n");
              return AVERROR_INVALIDDATA;
          }
 +        if (!s->ac && avctx->coder_type == -1) {
 +            av_log(avctx, AV_LOG_INFO, "bits_per_raw_sample > 8, forcing coder 1\n");
 +            s->ac = 2;
 +        }
          if (!s->ac) {
 -            av_log(avctx, AV_LOG_ERROR,
 -                   "bits_per_raw_sample of more than 8 needs -coder 1 currently\n");
 +            av_log(avctx, AV_LOG_ERROR, "bits_per_raw_sample of more than 8 needs -coder 1 currently\n");
-             return AVERROR_INVALIDDATA;
+             return AVERROR(ENOSYS);
          }
          s->version = FFMAX(s->version, 1);
 +    case AV_PIX_FMT_GRAY8:
      case AV_PIX_FMT_YUV444P:
 +    case AV_PIX_FMT_YUV440P:
      case AV_PIX_FMT_YUV422P:
      case AV_PIX_FMT_YUV420P:
      case AV_PIX_FMT_YUV411P:
          break;
      default:
          av_log(avctx, AV_LOG_ERROR, "format not supported\n");
-         return AVERROR_INVALIDDATA;
+         return AVERROR(ENOSYS);
      }
 -    avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_h_shift,
 -                                  &s->chroma_v_shift);
 +    if (s->transparency) {
 +        av_log(avctx, AV_LOG_WARNING, "Storing alpha plane, this will require a recent FFV1 decoder to playback!\n");
 +    }
 +    if (avctx->context_model > 1U) {
 +        av_log(avctx, AV_LOG_ERROR, "Invalid context model %d, valid values are 0 and 1\n", avctx->context_model);
 +        return AVERROR(EINVAL);
 +    }
 +
 +    if (s->ac > 1)
 +        for (i = 1; i < 256; i++)
 +            s->state_transition[i] = ver2_state[i];
 +
 +    for (i = 0; i < 256; i++) {
 +        s->quant_table_count = 2;
 +        if (s->bits_per_raw_sample <= 8) {
 +            s->quant_tables[0][0][i]=           quant11[i];
 +            s->quant_tables[0][1][i]=        11*quant11[i];
 +            s->quant_tables[0][2][i]=     11*11*quant11[i];
 +            s->quant_tables[1][0][i]=           quant11[i];
 +            s->quant_tables[1][1][i]=        11*quant11[i];
 +            s->quant_tables[1][2][i]=     11*11*quant5 [i];
 +            s->quant_tables[1][3][i]=   5*11*11*quant5 [i];
 +            s->quant_tables[1][4][i]= 5*5*11*11*quant5 [i];
 +        } else {
 +            s->quant_tables[0][0][i]=           quant9_10bit[i];
 +            s->quant_tables[0][1][i]=        11*quant9_10bit[i];
 +            s->quant_tables[0][2][i]=     11*11*quant9_10bit[i];
 +            s->quant_tables[1][0][i]=           quant9_10bit[i];
 +            s->quant_tables[1][1][i]=        11*quant9_10bit[i];
 +            s->quant_tables[1][2][i]=     11*11*quant5_10bit[i];
 +            s->quant_tables[1][3][i]=   5*11*11*quant5_10bit[i];
 +            s->quant_tables[1][4][i]= 5*5*11*11*quant5_10bit[i];
 +        }
 +    }
 +    s->context_count[0] = (11 * 11 * 11        + 1) / 2;
 +    s->context_count[1] = (11 * 11 * 5 * 5 * 5 + 1) / 2;
 +    memcpy(s->quant_table, s->quant_tables[avctx->context_model],
 +           sizeof(s->quant_table));
 +
 +    for (i = 0; i < s->plane_count; i++) {
 +        PlaneContext *const p = &s->plane[i];
 +
 +        memcpy(p->quant_table, s->quant_table, sizeof(p->quant_table));
 +        p->quant_table_index = avctx->context_model;
 +        p->context_count     = s->context_count[p->quant_table_index];
 +    }
 +
 +    if (ffv1_allocate_initial_states(s) < 0)
 +        return AVERROR(ENOMEM);
  
 +    avctx->coded_frame = &s->picture;
 +    if (!s->transparency)
 +        s->plane_count = 2;
 +    avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_h_shift, &s->chroma_v_shift);
      s->picture_number = 0;
  
      if (avctx->flags & (CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2)) {
          write_extra_header(s);
      }
  
-     if (ffv1_init_slice_contexts(s) < 0)
-         return -1;
-     if (ffv1_init_slices_state(s) < 0)
-         return -1;
+     if ((ret = ffv1_init_slice_contexts(s)) < 0)
+         return ret;
 -    if ((ret = ffv1_init_slice_state(s)) < 0)
++    if ((ret = ffv1_init_slices_state(s)) < 0)
+         return ret;
  
  #define STATS_OUT_SIZE 1024 * 1024 * 6
      if (avctx->flags & CODEC_FLAG_PASS1) {