Merge remote-tracking branch 'qatar/master'
authorMichael Niedermayer <michaelni@gmx.at>
Sun, 20 May 2012 20:41:58 +0000 (22:41 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Sun, 20 May 2012 20:58:04 +0000 (22:58 +0200)
* qatar/master:
  indeo: Make ivi_calc_band_checksum() static, it is only used in one file.
  indeo: Drop unused debug function ivi_check_band().
  avcodec/utils: cast a function argument to shut up a compiler warning
  truemotion1: remove disabled code
  fix typo in comment
  fate: fix dependencies for non-SAMPLES avconv tests
  indeo: check for invalid motion vectors
  indeo: check that band output buffer exists
  indeo: clear allocated band buffers
  indeo: track tile macroblock size
  indeo: check custom Huffman tables for errors
  factor out common decoding code for Indeo 4 and Indeo 5
  mp3: fix start band index for block type 2 in 8kHz audio
  lavf: change some (de)muxer names to lowercase
  lavf: make output format matching case insensitive

Conflicts:
libavcodec/indeo4.c
libavcodec/indeo5.c
libavcodec/ivi_common.c
libavcodec/utils.c
tests/fate/video.mak

Merged-by: Michael Niedermayer <michaelni@gmx.at>
16 files changed:
1  2 
libavcodec/imc.c
libavcodec/indeo4.c
libavcodec/indeo5.c
libavcodec/ivi_common.c
libavcodec/ivi_common.h
libavcodec/mpegaudiodec.c
libavcodec/truemotion1.c
libavcodec/utils.c
libavformat/idroqdec.c
libavformat/idroqenc.c
libavformat/iff.c
libavformat/iss.c
libavformat/mtv.c
libavformat/utils.c
tests/Makefile
tests/fate/video.mak

Simple merge
Simple merge
@@@ -91,9 -57,9 +57,9 @@@ enum 
   *  @param[in]     avctx  ptr to the AVCodecContext
   *  @return         result code: 0 = OK, -1 = error
   */
- static int decode_gop_header(IVI5DecContext *ctx, AVCodecContext *avctx)
+ static int decode_gop_header(IVI45DecContext *ctx, AVCodecContext *avctx)
  {
 -    int             result, i, p, tile_size, pic_size_indx, mb_size, blk_size;
 +    int             result, i, p, tile_size, pic_size_indx, mb_size, blk_size, is_scalable;
      int             quant_mat, blk_size_changed = 0;
      IVIBandDesc     *band, *band1, *band2;
      IVIPicConfig    pic_conf;
@@@ -869,7 -622,7 +659,6 @@@ static av_cold int decode_init(AVCodecC
      return 0;
  }
  
--
  AVCodec ff_indeo5_decoder = {
      .name           = "indeo5",
      .type           = AVMEDIA_TYPE_VIDEO,
@@@ -207,9 -212,9 +212,10 @@@ av_cold int ff_ivi_init_planes(IVIPlane
              band->width    = b_width;
              band->height   = b_height;
              band->pitch    = width_aligned;
-             band->bufs[0]  = av_malloc(buf_size);
-             band->bufs[1]  = av_malloc(buf_size);
+             band->aheight  = height_aligned;
+             band->bufs[0]  = av_mallocz(buf_size);
+             band->bufs[1]  = av_mallocz(buf_size);
 +            band->bufsize  = buf_size/2;
              if (!band->bufs[0] || !band->bufs[1])
                  return AVERROR(ENOMEM);
  
@@@ -632,6 -617,225 +629,242 @@@ void ff_ivi_output_plane(IVIPlaneDesc *
      }
  }
  
 -                return AVERROR_INVALIDDATA;
+ /**
+  *  Decode an Indeo 4 or 5 band.
+  *
+  *  @param[in,out]  ctx    ptr to the decoder context
+  *  @param[in,out]  band   ptr to the band descriptor
+  *  @param[in]      avctx  ptr to the AVCodecContext
+  *  @return         result code: 0 = OK, -1 = error
+  */
+ static int decode_band(IVI45DecContext *ctx, int plane_num,
+                        IVIBandDesc *band, AVCodecContext *avctx)
+ {
+     int         result, i, t, idx1, idx2, pos;
+     IVITile     *tile;
+     band->buf     = band->bufs[ctx->dst_buf];
+     if (!band->buf) {
+         av_log(avctx, AV_LOG_ERROR, "Band buffer points to no data!\n");
+         return AVERROR_INVALIDDATA;
+     }
+     band->ref_buf = band->bufs[ctx->ref_buf];
+     band->data_ptr = ctx->frame_data + (get_bits_count(&ctx->gb) >> 3);
+     result = ctx->decode_band_hdr(ctx, band, avctx);
+     if (result) {
+         av_log(avctx, AV_LOG_ERROR, "Error while decoding band header: %d\n",
+                result);
+         return result;
+     }
+     if (band->is_empty) {
+         av_log(avctx, AV_LOG_ERROR, "Empty band encountered!\n");
+         return AVERROR_INVALIDDATA;
+     }
+     band->rv_map = &ctx->rvmap_tabs[band->rvmap_sel];
+     /* apply corrections to the selected rvmap table if present */
+     for (i = 0; i < band->num_corr; i++) {
+         idx1 = band->corr[i * 2];
+         idx2 = band->corr[i * 2 + 1];
+         FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]);
+         FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]);
++        if (idx1 == band->rv_map->eob_sym || idx2 == band->rv_map->eob_sym)
++            band->rv_map->eob_sym ^= idx1 ^ idx2;
++        if (idx1 == band->rv_map->esc_sym || idx2 == band->rv_map->esc_sym)
++            band->rv_map->esc_sym ^= idx1 ^ idx2;
+     }
+     pos = get_bits_count(&ctx->gb);
+     for (t = 0; t < band->num_tiles; t++) {
+         tile = &band->tiles[t];
+         if (tile->mb_size != band->mb_size) {
+             av_log(avctx, AV_LOG_ERROR, "MB sizes mismatch: %d vs. %d\n",
+                    band->mb_size, tile->mb_size);
+             return AVERROR_INVALIDDATA;
+         }
+         tile->is_empty = get_bits1(&ctx->gb);
+         if (tile->is_empty) {
+             ff_ivi_process_empty_tile(avctx, band, tile,
+                                       (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3));
+             av_dlog(avctx, "Empty tile encountered!\n");
+         } else {
+             tile->data_size = ff_ivi_dec_tile_data_size(&ctx->gb);
+             if (!tile->data_size) {
+                 av_log(avctx, AV_LOG_ERROR, "Tile data size is zero!\n");
 -    if (result) {
++                result = AVERROR_INVALIDDATA;
++                break;
+             }
+             result = ctx->decode_mb_info(ctx, band, tile, avctx);
+             if (result < 0)
+                 break;
+             result = ff_ivi_decode_blocks(&ctx->gb, band, tile);
+             if (result < 0 || ((get_bits_count(&ctx->gb) - pos) >> 3) != tile->data_size) {
+                 av_log(avctx, AV_LOG_ERROR, "Corrupted tile data encountered!\n");
+                 break;
+             }
+             pos += tile->data_size << 3; // skip to next tile
+         }
+     }
+     /* restore the selected rvmap table by applying its corrections in reverse order */
+     for (i = band->num_corr-1; i >= 0; i--) {
+         idx1 = band->corr[i*2];
+         idx2 = band->corr[i*2+1];
+         FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]);
+         FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]);
++        if (idx1 == band->rv_map->eob_sym || idx2 == band->rv_map->eob_sym)
++            band->rv_map->eob_sym ^= idx1 ^ idx2;
++        if (idx1 == band->rv_map->esc_sym || idx2 == band->rv_map->esc_sym)
++            band->rv_map->esc_sym ^= idx1 ^ idx2;
+     }
+ #ifdef DEBUG
+     if (band->checksum_present) {
+         uint16_t chksum = ivi_calc_band_checksum(band);
+         if (chksum != band->checksum) {
+             av_log(avctx, AV_LOG_ERROR,
+                    "Band checksum mismatch! Plane %d, band %d, received: %x, calculated: %x\n",
+                    band->plane, band->band_num, band->checksum, chksum);
+         }
+     }
+ #endif
+     align_get_bits(&ctx->gb);
+     return result;
+ }
+ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+                         AVPacket *avpkt)
+ {
+     IVI45DecContext *ctx = avctx->priv_data;
+     const uint8_t   *buf = avpkt->data;
+     int             buf_size = avpkt->size;
+     int             result, p, b;
+     init_get_bits(&ctx->gb, buf, buf_size * 8);
+     ctx->frame_data = buf;
+     ctx->frame_size = buf_size;
+     result = ctx->decode_pic_hdr(ctx, avctx);
++    if (result || ctx->gop_invalid) {
+         av_log(avctx, AV_LOG_ERROR,
+                "Error while decoding picture header: %d\n", result);
+         return -1;
+     }
+     if (ctx->gop_flags & IVI5_IS_PROTECTED) {
+         av_log(avctx, AV_LOG_ERROR, "Password-protected clip!\n");
+         return -1;
+     }
+     ctx->switch_buffers(ctx);
+     //{ START_TIMER;
+     if (ctx->is_nonnull_frame(ctx)) {
++        ctx->buf_invalid[ctx->dst_buf] = 1;
+         for (p = 0; p < 3; p++) {
+             for (b = 0; b < ctx->planes[p].num_bands; b++) {
+                 result = decode_band(ctx, p, &ctx->planes[p].bands[b], avctx);
+                 if (result) {
+                     av_log(avctx, AV_LOG_ERROR,
+                            "Error while decoding band: %d, plane: %d\n", b, p);
+                     return -1;
+                 }
+             }
+         }
++        ctx->buf_invalid[ctx->dst_buf] = 0;
+     }
++    if (ctx->buf_invalid[ctx->dst_buf])
++        return -1;
+     //STOP_TIMER("decode_planes"); }
+     /* If the bidirectional mode is enabled, next I and the following P frame will */
+     /* be sent together. Unfortunately the approach below seems to be the only way */
+     /* to handle the B-frames mode. That's exactly the same Intel decoders do.     */
+     if (avctx->codec_id == CODEC_ID_INDEO4 && ctx->frame_type == 0/*FRAMETYPE_INTRA*/) {
+         while (get_bits(&ctx->gb, 8)); // skip version string
+         skip_bits_long(&ctx->gb, 64);  // skip padding, TODO: implement correct 8-bytes alignment
+         if (get_bits_left(&ctx->gb) > 18 && show_bits(&ctx->gb, 18) == 0x3FFF8)
+             av_log(avctx, AV_LOG_ERROR, "Buffer contains IP frames!\n");
+     }
++    if (avctx->codec_id == CODEC_ID_INDEO4 && !ctx->is_nonnull_frame(ctx))
++        return buf_size;
++
+     if (ctx->frame.data[0])
+         avctx->release_buffer(avctx, &ctx->frame);
++    avcodec_set_dimensions(avctx, ctx->planes[0].width, ctx->planes[0].height);
+     ctx->frame.reference = 0;
+     if ((result = avctx->get_buffer(avctx, &ctx->frame)) < 0) {
+         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+         return result;
+     }
+     if (ctx->is_scalable) {
+         if (avctx->codec_id == CODEC_ID_INDEO4)
+             ff_ivi_recompose_haar(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0], 4);
+         else
+             ff_ivi_recompose53   (&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0], 4);
+     } else {
+         ff_ivi_output_plane(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0]);
+     }
+     ff_ivi_output_plane(&ctx->planes[2], ctx->frame.data[1], ctx->frame.linesize[1]);
+     ff_ivi_output_plane(&ctx->planes[1], ctx->frame.data[2], ctx->frame.linesize[2]);
+     *data_size = sizeof(AVFrame);
+     *(AVFrame*)data = ctx->frame;
+     return buf_size;
+ }
+ /**
+  *  Close Indeo5 decoder and clean up its context.
+  */
+ av_cold int ff_ivi_decode_close(AVCodecContext *avctx)
+ {
+     IVI45DecContext *ctx = avctx->priv_data;
+     ff_ivi_free_buffers(&ctx->planes[0]);
+     if (ctx->mb_vlc.cust_tab.table)
+         ff_free_vlc(&ctx->mb_vlc.cust_tab);
+     if (ctx->frame.data[0])
+         avctx->release_buffer(avctx, &ctx->frame);
+ #if IVI4_STREAM_ANALYSER
+     if (avctx->codec_id == CODEC_ID_INDEO4) {
+     if (ctx->is_scalable)
+         av_log(avctx, AV_LOG_ERROR, "This video uses scalability mode!\n");
+     if (ctx->uses_tiling)
+         av_log(avctx, AV_LOG_ERROR, "This video uses local decoding!\n");
+     if (ctx->has_b_frames)
+         av_log(avctx, AV_LOG_ERROR, "This video contains B-frames!\n");
+     if (ctx->has_transp)
+         av_log(avctx, AV_LOG_ERROR, "Transparency mode is enabled!\n");
+     if (ctx->uses_haar)
+         av_log(avctx, AV_LOG_ERROR, "This video uses Haar transform!\n");
+     if (ctx->uses_fullpel)
+         av_log(avctx, AV_LOG_ERROR, "This video uses fullpel motion vectors!\n");
+     }
+ #endif
+     return 0;
+ }
  
  /**
   * These are 2x8 predefined Huffman codebooks for coding macroblock/block
@@@ -193,6 -196,60 +197,63 @@@ typedef struct 
      uint8_t     chroma_bands;
  } IVIPicConfig;
  
+ typedef struct IVI45DecContext {
+     GetBitContext   gb;
+     AVFrame         frame;
+     RVMapDesc       rvmap_tabs[9];   ///< local corrected copy of the static rvmap tables
+     uint32_t        frame_num;
+     int             frame_type;
+     int             prev_frame_type; ///< frame type of the previous frame
+     uint32_t        data_size;       ///< size of the frame data in bytes from picture header
+     int             is_scalable;
+     int             transp_status;   ///< transparency mode status: 1 - enabled
+     const uint8_t   *frame_data;     ///< input frame data pointer
+     int             inter_scal;      ///< signals a sequence of scalable inter frames
+     uint32_t        frame_size;      ///< frame size in bytes
+     uint32_t        pic_hdr_size;    ///< picture header size in bytes
+     uint8_t         frame_flags;
+     uint16_t        checksum;        ///< frame checksum
+     IVIPicConfig    pic_conf;
+     IVIPlaneDesc    planes[3];       ///< color planes
+     int             buf_switch;      ///< used to switch between three buffers
+     int             dst_buf;         ///< buffer index for the currently decoded frame
+     int             ref_buf;         ///< inter frame reference buffer index
+     int             ref2_buf;        ///< temporal storage for switching buffers
+     IVIHuffTab      mb_vlc;          ///< current macroblock table descriptor
+     IVIHuffTab      blk_vlc;         ///< current block table descriptor
+     uint8_t         rvmap_sel;
+     uint8_t         in_imf;
+     uint8_t         in_q;            ///< flag for explicitly stored quantiser delta
+     uint8_t         pic_glob_quant;
+     uint8_t         unknown1;
+     uint16_t        gop_hdr_size;
+     uint8_t         gop_flags;
+     uint32_t        lock_word;
+ #if IVI4_STREAM_ANALYSER
+     uint8_t         has_b_frames;
+     uint8_t         has_transp;
+     uint8_t         uses_tiling;
+     uint8_t         uses_haar;
+     uint8_t         uses_fullpel;
+ #endif
+     int             (*decode_pic_hdr)  (struct IVI45DecContext *ctx, AVCodecContext *avctx);
+     int             (*decode_band_hdr) (struct IVI45DecContext *ctx, IVIBandDesc *band, AVCodecContext *avctx);
+     int             (*decode_mb_info)  (struct IVI45DecContext *ctx, IVIBandDesc *band, IVITile *tile, AVCodecContext *avctx);
+     void            (*switch_buffers)  (struct IVI45DecContext *ctx);
+     int             (*is_nonnull_frame)(struct IVI45DecContext *ctx);
++
++    int gop_invalid;
++    int buf_invalid[3];
+ } IVI45DecContext;
  /** compare some properties of two pictures */
  static inline int ivi_pic_config_cmp(IVIPicConfig *str1, IVIPicConfig *str2)
  {
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc tests/Makefile
@@@ -86,18 -74,18 +86,18 @@@ FATE_LAVF    = $(LAVF_TESTS:%=fate-lavf
  FATE_LAVFI   = $(LAVFI_TESTS:%=fate-lavfi-%)
  FATE_SEEK    = $(SEEK_TESTS:seek_%=fate-seek-%)
  
- FATE = $(FATE_ACODEC)                                                   \
-        $(FATE_VCODEC)                                                   \
-        $(FATE_LAVF)                                                     \
-        $(FATE_SEEK)                                                     \
+ FATE_AVCONV += $(FATE_ACODEC)                                           \
+                $(FATE_VCODEC)                                           \
+                $(FATE_LAVF)                                             \
+                $(FATE_LAVFI)                                            \
+                $(FATE_SEEK)                                             \
  
 -FATE_AVCONV += $(FATE_AVCONV-yes)
 -FATE-$(CONFIG_AVCONV) += $(FATE_AVCONV)
 +FATE_FFMPEG += $(FATE_FFMPEG-yes) $(FATE_AVCONV) $(FATE_AVCONV-yes)
 +FATE-$(CONFIG_FFMPEG) += $(FATE_FFMPEG)
  
  FATE-$(CONFIG_AVCODEC)  += $(FATE_LIBAVCODEC)
- FATE-$(CONFIG_AVFILTER) += $(FATE_LAVFI)
  
 -FATE_SAMPLES-$(CONFIG_AVCONV) += $(FATE_SAMPLES_AVCONV)
 +FATE_SAMPLES-$(CONFIG_FFMPEG) += $(FATE_SAMPLES_AVCONV) $(FATE_SAMPLES_FFMPEG)
  FATE_SAMPLES += $(FATE_SAMPLES-yes)
  
  FATE += $(FATE-yes)
@@@ -109,17 -109,17 +109,17 @@@ fate-flic-af12: CMD = framecrc -i $(SAM
  FATE_FLIC += fate-flic-magiccarpet
  fate-flic-magiccarpet: CMD = framecrc -i $(SAMPLES)/fli/intel.dat -pix_fmt rgb24
  
 -FATE_SAMPLES_AVCONV += $(FATE_FLIC)
 +FATE_VIDEO += $(FATE_FLIC)
  fate-flic: $(FATE_FLIC)
  
 -FATE_SAMPLES_AVCONV += fate-frwu
 +FATE_VIDEO += fate-frwu
  fate-frwu: CMD = framecrc -i $(SAMPLES)/frwu/frwu.avi
  
 -FATE_SAMPLES_AVCONV += fate-id-cin-video
 +FATE_VIDEO += fate-id-cin-video
  fate-id-cin-video: CMD = framecrc -i $(SAMPLES)/idcin/idlog-2MB.cin -pix_fmt rgb24
  
 -FATE_SAMPLES_AVCONV += fate-idroq-video-encode
 +FATE_VIDEO-$(CONFIG_AVFILTER) += fate-idroq-video-encode
- fate-idroq-video-encode: CMD = md5 -f image2 -vcodec pgmyuv -i $(SAMPLES)/ffmpeg-synthetic/vsynth1/%02d.pgm -sws_flags +bitexact -vf pad=512:512:80:112 -f RoQ -t 0.2
+ fate-idroq-video-encode: CMD = md5 -f image2 -vcodec pgmyuv -i $(SAMPLES)/ffmpeg-synthetic/vsynth1/%02d.pgm -sws_flags +bitexact -vf pad=512:512:80:112 -f roq -t 0.2
  
  FATE_IFF += fate-iff-byterun1
  fate-iff-byterun1: CMD = framecrc -i $(SAMPLES)/iff/ASH.LBM -pix_fmt rgb24