Merge remote-tracking branch 'qatar/master'
authorMichael Niedermayer <michaelni@gmx.at>
Mon, 16 Jan 2012 00:20:32 +0000 (01:20 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Mon, 16 Jan 2012 00:33:35 +0000 (01:33 +0100)
* qatar/master:
  fate: split ADPCM and DPCM test references into separate files.
  mov, mxfdec: Employ more meaningful return values.
  lavc: Relax API strictness in avcodec_decode_audio3 with a custom get_buffer()
  wavpack: fix clipping for 32-bit lossy mode
  vb: Use bytestream2 functions

Conflicts:
libavcodec/utils.c
libavcodec/vb.c
libavformat/mxfdec.c
tests/fate/dpcm.mak

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavcodec/avcodec.h
libavcodec/utils.c
libavcodec/vb.c
libavcodec/wavpack.c
libavformat/mov.c
libavformat/mxfdec.c
tests/Makefile
tests/fate/dpcm.mak

Simple merge
@@@ -1057,10 -933,11 +1057,12 @@@ int attribute_align_arg avcodec_decode_
      int ret, got_frame = 0;
  
      if (avctx->get_buffer != avcodec_default_get_buffer) {
-         av_log(avctx, AV_LOG_ERROR, "Overriding custom get_buffer() for "
-                "avcodec_decode_audio3()\n");
+         av_log(avctx, AV_LOG_ERROR, "Custom get_buffer() for use with"
+                "avcodec_decode_audio3() detected. Overriding with avcodec_default_get_buffer\n");
+         av_log(avctx, AV_LOG_ERROR, "Please port your application to "
+                "avcodec_decode_audio4()\n");
          avctx->get_buffer = avcodec_default_get_buffer;
 +        avctx->release_buffer = avcodec_default_release_buffer;
      }
  
      ret = avcodec_decode_audio4(avctx, &frame, &got_frame, avpkt);
diff --cc libavcodec/vb.c
@@@ -73,7 -73,7 +73,7 @@@ static void vb_decode_palette(VBDecCont
          return;
      }
      for(i = start; i <= start + size; i++)
-         c->pal[i] = 0xFF << 24 | bytestream_get_be24(&c->stream);
 -        c->pal[i] = bytestream2_get_be24(&c->stream);
++        c->pal[i] = 0xFFU << 24 | bytestream2_get_be24(&c->stream);
  }
  
  static inline int check_pixel(uint8_t *buf, uint8_t *start, uint8_t *end)
@@@ -200,49 -191,33 +191,37 @@@ static int decode_frame(AVCodecContext 
      int i, j;
      int flags;
      uint32_t size;
-     int rest = buf_size;
      int offset = 0;
  
+     bytestream2_init(&c->stream, avpkt->data, avpkt->size);
      if(c->pic.data[0])
          avctx->release_buffer(avctx, &c->pic);
 -    c->pic.reference = 1;
 +    c->pic.reference = 3;
      if(avctx->get_buffer(avctx, &c->pic) < 0){
          av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
          return -1;
      }
  
-     c->stream = buf;
-     flags = bytestream_get_le16(&c->stream);
-     rest -= 2;
+     flags = bytestream2_get_le16(&c->stream);
  
      if(flags & VB_HAS_GMC){
-         i = (int16_t)bytestream_get_le16(&c->stream);
-         j = (int16_t)bytestream_get_le16(&c->stream);
+         i = (int16_t)bytestream2_get_le16(&c->stream);
+         j = (int16_t)bytestream2_get_le16(&c->stream);
          offset = i + j * avctx->width;
-         rest -= 4;
-     }
-     if(rest < 0){
-         av_log(avctx, AV_LOG_ERROR, "not enough data\n");
-         return -1;
      }
      if(flags & VB_HAS_VIDEO){
-         size = bytestream_get_le32(&c->stream);
-         if(size > rest || size<4){
+         size = bytestream2_get_le32(&c->stream);
++        if(size > bytestream2_get_bytes_left(&c->stream)+4 || size<4){
 +            av_log(avctx, AV_LOG_ERROR, "Frame size invalid\n");
 +            return -1;
 +        }
-         vb_decode_framedata(c, c->stream, size, offset);
-         c->stream += size - 4;
-         rest -= size;
+         vb_decode_framedata(c, offset);
+         bytestream2_skip(&c->stream, size - 4);
      }
      if(flags & VB_HAS_PALETTE){
-         size = bytestream_get_le32(&c->stream);
-         if(size > rest){
-             av_log(avctx, AV_LOG_ERROR, "Palette size is too big\n");
-             return -1;
-         }
+         size = bytestream2_get_le32(&c->stream);
          vb_decode_palette(c, size);
-         rest -= size;
      }
  
      memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE);
Simple merge
@@@ -912,16 -896,12 +915,16 @@@ static int mov_read_extradata(MOVContex
      if (c->fc->nb_streams < 1) // will happen with jp2 files
          return 0;
      st= c->fc->streams[c->fc->nb_streams-1];
 +
 +    if (st->codec->codec_id != codec_id)
 +        return 0; /* unexpected codec_id - don't mess with extradata */
 +
      size= (uint64_t)st->codec->extradata_size + atom.size + 8 + FF_INPUT_BUFFER_PADDING_SIZE;
      if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
-         return -1;
+         return AVERROR_INVALIDDATA;
      buf= av_realloc(st->codec->extradata, size);
      if (!buf)
-         return -1;
+         return AVERROR(ENOMEM);
      st->codec->extradata= buf;
      buf+= st->codec->extradata_size;
      st->codec->extradata_size= size - FF_INPUT_BUFFER_PADDING_SIZE;
@@@ -1272,8 -734,7 +1273,8 @@@ static int mxf_parse_structural_metadat
              for (k = 0; k < source_package->tracks_count; k++) {
                  if (!(temp_track = mxf_resolve_strong_ref(mxf, &source_package->tracks_refs[k], Track))) {
                      av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track strong ref\n");
-                     ret = -1;
 -                    return AVERROR_INVALIDDATA;
++                    ret = AVERROR_INVALIDDATA;
 +                    goto fail_and_free;
                  }
                  if (temp_track->track_id == component->source_track_id) {
                      source_track = temp_track;
@@@ -1445,8 -882,9 +1446,9 @@@ static int mxf_read_local_tags(MXFConte
      uint64_t klv_end = avio_tell(pb) + klv->length;
  
      if (!ctx)
-         return -1;
+         return AVERROR(ENOMEM);
 -    while (avio_tell(pb) + 4 < klv_end) {
 +    while (avio_tell(pb) + 4 < klv_end && !url_feof(pb)) {
+         int ret;
          int tag = avio_rb16(pb);
          int size = avio_rb16(pb); /* KLV specified by 0x53 */
          uint64_t next = avio_tell(pb) + size;
          }
          if (ctx_size && tag == 0x3C0A)
              avio_read(pb, ctx->uid, 16);
-         else if (read_child(ctx, pb, tag, size, uid, -1) < 0)
-             return -1;
 -        else if ((ret = read_child(ctx, pb, tag, size, uid)) < 0)
++        else if ((ret = read_child(ctx, pb, tag, size, uid, -1)) < 0)
+             return ret;
  
 +        /* accept the 64k local set limit being exceeded (Avid)
 +         * don't accept it extending past the end of the KLV though (zzuf5.mxf) */
 +        if (avio_tell(pb) > klv_end) {
 +            av_log(mxf->fc, AV_LOG_ERROR, "local tag %#04x extends past end of local set @ %#"PRIx64"\n",
 +                   tag, klv->offset);
 +            return AVERROR_INVALIDDATA;
 +        } else if (avio_tell(pb) <= next)   /* only seek forward, else this can loop for a long time */
          avio_seek(pb, next, SEEK_SET);
      }
      if (ctx_size) ctx->type = type;
@@@ -1680,22 -948,11 +1682,22 @@@ static int mxf_read_header(AVFormatCont
                  int res;
                  if (klv.key[5] == 0x53) {
                      res = mxf_read_local_tags(mxf, &klv, metadata->read, metadata->ctx_size, metadata->type);
 -                } else
 -                    res = metadata->read(mxf, s->pb, 0, 0, NULL);
 +                } else {
 +                    uint64_t next = avio_tell(s->pb) + klv.length;
 +                    res = metadata->read(mxf, s->pb, 0, klv.length, klv.key, klv.offset);
 +
 +                    /* only seek forward, else this can loop for a long time */
 +                    if (avio_tell(s->pb) > next) {
 +                        av_log(s, AV_LOG_ERROR, "read past end of KLV @ %#"PRIx64"\n",
 +                               klv.offset);
 +                        return AVERROR_INVALIDDATA;
 +                    }
 +
 +                    avio_seek(s->pb, next, SEEK_SET);
 +                }
                  if (res < 0) {
                      av_log(s, AV_LOG_ERROR, "error reading header metadata\n");
-                     return -1;
+                     return res;
                  }
                  break;
              }
          if (!metadata->read)
              avio_skip(s->pb, klv.length);
      }
 -    return mxf_parse_structural_metadata(mxf);
 +    /* FIXME avoid seek */
 +    if (!essence_offset)  {
 +        av_log(s, AV_LOG_ERROR, "no essence\n");
 +        return AVERROR_INVALIDDATA;
 +    }
 +    avio_seek(s->pb, essence_offset, SEEK_SET);
 +
 +    mxf_compute_essence_containers(mxf);
 +
 +    /* we need to do this before computing the index tables
 +     * to be able to fill in zero IndexDurations with st->duration */
 +    if ((ret = mxf_parse_structural_metadata(mxf)) < 0)
 +        return ret;
 +
 +    if ((ret = mxf_compute_index_tables(mxf)) < 0)
 +        return ret;
 +
 +    if (mxf->nb_index_tables > 1) {
 +        /* TODO: look up which IndexSID to use via EssenceContainerData */
 +        av_log(mxf->fc, AV_LOG_INFO, "got %i index tables - only the first one (IndexSID %i) will be used\n",
 +               mxf->nb_index_tables, mxf->index_tables[0].index_sid);
 +    } else if (mxf->nb_index_tables == 0 && mxf->op == OPAtom) {
 +        av_log(mxf->fc, AV_LOG_ERROR, "cannot demux OPAtom without an index\n");
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    return 0;
 +}
 +
 +/**
 + * Computes DTS and PTS for the given video packet based on its offset.
 + */
 +static void mxf_packet_timestamps(MXFContext *mxf, AVPacket *pkt)
 +{
 +    int64_t last_ofs = -1, next_ofs;
 +    MXFIndexTable *t = &mxf->index_tables[0];
 +
 +    /* this is called from the OP1a demuxing logic, which means there may be no index tables */
 +    if (mxf->nb_index_tables <= 0)
 +        return;
 +
 +    /* find mxf->current_edit_unit so that the next edit unit starts ahead of pkt->pos */
 +    while (mxf->current_edit_unit >= 0) {
 +        if (mxf_edit_unit_absolute_offset(mxf, t, mxf->current_edit_unit + 1, NULL, &next_ofs, 0) < 0)
 +            break;
 +
 +        if (next_ofs <= last_ofs) {
 +            /* large next_ofs didn't change or current_edit_unit wrapped around
 +             * this fixes the infinite loop on zzuf3.mxf */
 +            av_log(mxf->fc, AV_LOG_ERROR, "next_ofs didn't change. not deriving packet timestamps\n");
 +            return;
 +        }
 +
 +        if (next_ofs > pkt->pos)
 +            break;
 +
 +        last_ofs = next_ofs;
 +        mxf->current_edit_unit++;
 +    }
 +
 +    if (mxf->current_edit_unit < 0 || mxf->current_edit_unit >= t->nb_ptses)
 +        return;
 +
 +    pkt->dts = mxf->current_edit_unit + t->first_dts;
 +    pkt->pts = t->ptses[mxf->current_edit_unit];
 +}
 +
 +static int mxf_read_packet_old(AVFormatContext *s, AVPacket *pkt)
 +{
 +    KLVPacket klv;
 +
 +    while (!url_feof(s->pb)) {
++        int ret;
 +        if (klv_read_packet(&klv, s->pb) < 0)
 +            return -1;
 +        PRINT_KEY(s, "read packet", klv.key);
 +        av_dlog(s, "size %"PRIu64" offset %#"PRIx64"\n", klv.length, klv.offset);
 +        if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key)) {
-             int res = mxf_decrypt_triplet(s, pkt, &klv);
-             if (res < 0) {
++            ret = mxf_decrypt_triplet(s, pkt, &klv);
++            if (ret < 0) {
 +                av_log(s, AV_LOG_ERROR, "invalid encoded triplet\n");
-                 return -1;
++                return AVERROR_INVALIDDATA;
 +            }
 +            return 0;
 +        }
 +        if (IS_KLV_KEY(klv.key, mxf_essence_element_key) ||
 +            IS_KLV_KEY(klv.key, mxf_avid_essence_element_key)) {
 +            int index = mxf_get_stream_index(s, &klv);
 +            if (index < 0) {
 +                av_log(s, AV_LOG_ERROR, "error getting stream index %d\n", AV_RB32(klv.key+12));
 +                goto skip;
 +            }
 +            if (s->streams[index]->discard == AVDISCARD_ALL)
 +                goto skip;
 +            /* check for 8 channels AES3 element */
 +            if (klv.key[12] == 0x06 && klv.key[13] == 0x01 && klv.key[14] == 0x10) {
 +                if (mxf_get_d10_aes3_packet(s->pb, s->streams[index], pkt, klv.length) < 0) {
 +                    av_log(s, AV_LOG_ERROR, "error reading D-10 aes3 frame\n");
-                     return -1;
++                    return AVERROR_INVALIDDATA;
 +                }
 +            } else {
-                 int ret = av_get_packet(s->pb, pkt, klv.length);
++                ret = av_get_packet(s->pb, pkt, klv.length);
 +                if (ret < 0)
 +                    return ret;
 +            }
 +            pkt->stream_index = index;
 +            pkt->pos = klv.offset;
 +
 +            if (s->streams[index]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
 +                mxf_packet_timestamps(s->priv_data, pkt);   /* offset -> EditUnit -> DTS/PTS */
 +
 +            return 0;
 +        } else
 +        skip:
 +            avio_skip(s->pb, klv.length);
 +    }
 +    return AVERROR_EOF;
 +}
 +
 +static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)
 +{
 +    MXFContext *mxf = s->priv_data;
 +    int ret, size;
 +    int64_t ret64, pos, next_pos;
 +    AVStream *st;
 +    MXFIndexTable *t;
 +
 +    if (mxf->op != OPAtom)
 +        return mxf_read_packet_old(s, pkt);
 +
 +    /* OPAtom - clip wrapped demuxing */
 +    /* NOTE: mxf_read_header() makes sure nb_index_tables > 0 for OPAtom */
 +    st = s->streams[0];
 +    t = &mxf->index_tables[0];
 +
 +    if (mxf->current_edit_unit >= st->duration)
 +        return AVERROR_EOF;
 +
 +    if ((ret = mxf_edit_unit_absolute_offset(mxf, t, mxf->current_edit_unit, NULL, &pos, 1)) < 0)
 +        return ret;
 +
 +    /* compute size by finding the next edit unit or the end of the essence container
 +     * not pretty, but it works */
 +    if ((ret = mxf_edit_unit_absolute_offset(mxf, t, mxf->current_edit_unit + 1, NULL, &next_pos, 0)) < 0 &&
 +        (next_pos = mxf_essence_container_end(mxf, t->body_sid)) <= 0) {
 +        av_log(s, AV_LOG_ERROR, "unable to compute the size of the last packet\n");
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    if ((size = next_pos - pos) <= 0) {
 +        av_log(s, AV_LOG_ERROR, "bad size: %i\n", size);
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    if ((ret64 = avio_seek(s->pb, pos, SEEK_SET)) < 0)
 +        return ret64;
 +
 +        if ((ret = av_get_packet(s->pb, pkt, size)) != size)
 +            return ret < 0 ? ret : AVERROR_EOF;
 +
 +    if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && t->ptses &&
 +        mxf->current_edit_unit >= 0 && mxf->current_edit_unit < t->nb_ptses) {
 +        pkt->dts = mxf->current_edit_unit + t->first_dts;
 +        pkt->pts = t->ptses[mxf->current_edit_unit];
 +    }
 +
 +    pkt->stream_index = 0;
 +    mxf->current_edit_unit++;
 +
 +    return 0;
  }
  
  static int mxf_read_close(AVFormatContext *s)
@@@ -1944,14 -1018,9 +1947,14 @@@ static int mxf_read_seek(AVFormatContex
  {
      AVStream *st = s->streams[stream_index];
      int64_t seconds;
 +    MXFContext* mxf = s->priv_data;
 +    int64_t seekpos;
 +    int ret;
 +    MXFIndexTable *t;
  
 +    if (mxf->index_tables <= 0) {
      if (!s->bit_rate)
-         return -1;
+         return AVERROR_INVALIDDATA;
      if (sample_time < 0)
          sample_time = 0;
      seconds = av_rescale(sample_time, st->time_base.num, st->time_base.den);
diff --cc tests/Makefile
Simple merge
@@@ -1,44 -1,6 +1,8 @@@
- FATE_DPCM += fate-adpcm-ea-r2
- fate-adpcm-ea-r2: CMD = crc -i $(SAMPLES)/ea-mpc/THX_logo.mpc -vn
- FATE_DPCM += fate-adpcm-ea-r3
- fate-adpcm-ea-r3: CMD = crc -i $(SAMPLES)/ea-vp6/THX_logo.vp6 -vn
- FATE_DPCM += fate-creative-adpcm
- fate-creative-adpcm: CMD = md5 -i $(SAMPLES)/creative/intro-partial.wav -f s16le
- FATE_DPCM += fate-creative-adpcm-8-2bit
- fate-creative-adpcm-8-2bit: CMD = md5 -i $(SAMPLES)/creative/BBC_2BIT.VOC -f s16le
- FATE_DPCM += fate-creative-adpcm-8-2.6bit
- fate-creative-adpcm-8-2.6bit: CMD = md5 -i $(SAMPLES)/creative/BBC_3BIT.VOC -f s16le
- FATE_DPCM += fate-creative-adpcm-8-4bit
- fate-creative-adpcm-8-4bit: CMD = md5 -i $(SAMPLES)/creative/BBC_4BIT.VOC -f s16le
- FATE_DPCM += fate-ea-mad-adpcm-ea-r1
- fate-ea-mad-adpcm-ea-r1: CMD = framecrc -i $(SAMPLES)/ea-mad/NFS6LogoE.mad
- FATE_DPCM += fate-ea-tqi-adpcm
- fate-ea-tqi-adpcm: CMD = framecrc -i $(SAMPLES)/ea-wve/networkBackbone-partial.wve -frames:v 26
 -FATE_TESTS += fate-idroq-video-dpcm
 +FATE_DPCM += fate-idroq-video-dpcm
  fate-idroq-video-dpcm: CMD = framecrc -i $(SAMPLES)/idroq/idlogo.roq
  
- FATE_DPCM += fate-psx-str-v3-adpcm_xa
- fate-psx-str-v3-adpcm_xa: CMD = framecrc -i $(SAMPLES)/psx-str/abc000_cut.str -vn
- FATE_DPCM += fate-qt-msadpcm-stereo
- fate-qt-msadpcm-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-L-ms02.mov -f s16le
- FATE_DPCM += fate-qt-msimaadpcm-stereo
- fate-qt-msimaadpcm-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-L-ms11.mov -f s16le
- FATE_DPCM += fate-thp-mjpeg-adpcm
- fate-thp-mjpeg-adpcm: CMD = framecrc -idct simple -i $(SAMPLES)/thp/pikmin2-opening1-partial.thp
 -FATE_TESTS += fate-dpcm-xan
 +FATE_DPCM += fate-dpcm-xan
  fate-dpcm-xan: CMD = md5 -i $(SAMPLES)/wc4-xan/wc4_2.avi -vn -f s16le
  
 +FATE_TESTS += $(FATE_DPCM)
 +fate-dpcm: $(FATE_DPCM)