]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/indeo5.c
rtsp: Make the rtsp flags avoptions set via a define
[ffmpeg] / libavcodec / indeo5.c
index fa150f20bda91ea33b7f342ddaf0ecfbf67bacd2..ba1bc18eff4f996d6a2e002d44e435e495053ad0 100644 (file)
@@ -2,25 +2,25 @@
  * Indeo Video Interactive v5 compatible decoder
  * Copyright (c) 2009 Maxim Poliakovski
  *
- * This file is part of FFmpeg.
+ * This file is part of Libav.
  *
- * FFmpeg is free software; you can redistribute it and/or
+ * Libav is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * FFmpeg is distributed in the hope that it will be useful,
+ * Libav is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
+ * License along with Libav; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 /**
- * @file libavcodec/indeo5.c
+ * @file
  * Indeo Video Interactive version 5 decoder
  *
  * Indeo5 data is usually transported within .avi or .mov files.
@@ -57,8 +57,10 @@ typedef struct {
     IVIPlaneDesc    planes[3];       ///< color planes
     const uint8_t   *frame_data;     ///< input frame data pointer
     int             buf_switch;      ///< used to switch between three buffers
-    int             dst_buf;
-    int             ref_buf;
+    int             inter_scal;      ///< signals a sequence of scalable inter frames
+    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
     uint32_t        frame_size;      ///< frame size in bytes
     int             frame_type;
     int             prev_frame_type; ///< frame type of the previous frame
@@ -78,17 +80,18 @@ typedef struct {
 
 
 /**
- *  Decodes Indeo5 GOP (Group of pictures) header.
+ *  Decode Indeo5 GOP (Group of pictures) header.
  *  This header is present in key frames only.
  *  It defines parameters for all frames in a GOP.
  *
- *  @param ctx      [in,out] ptr to the decoder context
- *  @param avctx    [in] ptr to the AVCodecContext
+ *  @param[in,out] ctx    ptr to the decoder context
+ *  @param[in]     avctx  ptr to the AVCodecContext
  *  @return         result code: 0 = OK, -1 = error
  */
 static int decode_gop_header(IVI5DecContext *ctx, AVCodecContext *avctx)
 {
-    int             result, i, p, tile_size, pic_size_indx, mb_size, blk_size, blk_size_changed = 0;
+    int             result, i, p, tile_size, pic_size_indx, mb_size, blk_size;
+    int             quant_mat, blk_size_changed = 0;
     IVIBandDesc     *band, *band1, *band2;
     IVIPicConfig    pic_conf;
 
@@ -183,25 +186,25 @@ static int decode_gop_header(IVI5DecContext *ctx, AVCodecContext *avctx)
             case 1:
                 band->inv_transform = ff_ivi_row_slant8;
                 band->dc_transform  = ff_ivi_dc_row_slant;
-                band->scan          = ivi5_scans8x8[0];
+                band->scan          = ff_ivi_vertical_scan_8x8;
                 break;
 
             case 2:
                 band->inv_transform = ff_ivi_col_slant8;
                 band->dc_transform  = ff_ivi_dc_col_slant;
-                band->scan          = ivi5_scans8x8[1];
+                band->scan          = ff_ivi_horizontal_scan_8x8;
                 break;
 
             case 3:
                 band->inv_transform = ff_ivi_put_pixels_8x8;
                 band->dc_transform  = ff_ivi_put_dc_pixel_8x8;
-                band->scan          = ivi5_scans8x8[1];
+                band->scan          = ff_ivi_horizontal_scan_8x8;
                 break;
 
             case 4:
                 band->inv_transform = ff_ivi_inverse_slant_4x4;
                 band->dc_transform  = ff_ivi_dc_slant_2d;
-                band->scan          = ivi5_scan4x4;
+                band->scan          = ff_ivi_direct_scan_4x4;
                 break;
             }
 
@@ -210,9 +213,21 @@ static int decode_gop_header(IVI5DecContext *ctx, AVCodecContext *avctx)
 
             /* select dequant matrix according to plane and band number */
             if (!p) {
-                band->quant_mat = (pic_conf.luma_bands > 1) ? i+1 : 0;
+                quant_mat = (pic_conf.luma_bands > 1) ? i+1 : 0;
             } else {
-                band->quant_mat = 5;
+                quant_mat = 5;
+            }
+
+            if (band->blk_size == 8) {
+                band->intra_base  = &ivi5_base_quant_8x8_intra[quant_mat][0];
+                band->inter_base  = &ivi5_base_quant_8x8_inter[quant_mat][0];
+                band->intra_scale = &ivi5_scale_quant_8x8_intra[quant_mat][0];
+                band->inter_scale = &ivi5_scale_quant_8x8_inter[quant_mat][0];
+            } else {
+                band->intra_base  = ivi5_base_quant_4x4_intra;
+                band->inter_base  = ivi5_base_quant_4x4_inter;
+                band->intra_scale = ivi5_scale_quant_4x4_intra;
+                band->inter_scale = ivi5_scale_quant_4x4_inter;
             }
 
             if (get_bits(&ctx->gb, 2)) {
@@ -232,7 +247,10 @@ static int decode_gop_header(IVI5DecContext *ctx, AVCodecContext *avctx)
         band2->mb_size       = band1->mb_size;
         band2->blk_size      = band1->blk_size;
         band2->is_halfpel    = band1->is_halfpel;
-        band2->quant_mat     = band1->quant_mat;
+        band2->intra_base    = band1->intra_base;
+        band2->inter_base    = band1->inter_base;
+        band2->intra_scale   = band1->intra_scale;
+        band2->inter_scale   = band1->inter_scale;
         band2->scan          = band1->scan;
         band2->inv_transform = band1->inv_transform;
         band2->dc_transform  = band1->dc_transform;
@@ -278,9 +296,9 @@ static int decode_gop_header(IVI5DecContext *ctx, AVCodecContext *avctx)
 
 
 /**
- *  Skips a header extension.
+ *  Skip a header extension.
  *
- *  @param gb   [in,out] the GetBit context
+ *  @param[in,out]  gb  the GetBit context
  */
 static inline void skip_hdr_extension(GetBitContext *gb)
 {
@@ -294,10 +312,10 @@ static inline void skip_hdr_extension(GetBitContext *gb)
 
 
 /**
- *  Decodes Indeo5 picture header.
+ *  Decode Indeo5 picture header.
  *
- *  @param ctx      [in,out] ptr to the decoder context
- *  @param avctx    [in] ptr to the AVCodecContext
+ *  @param[in,out]  ctx    ptr to the decoder context
+ *  @param[in]      avctx  ptr to the AVCodecContext
  *  @return         result code: 0 = OK, -1 = error
  */
 static int decode_pic_hdr(IVI5DecContext *ctx, AVCodecContext *avctx)
@@ -346,11 +364,11 @@ static int decode_pic_hdr(IVI5DecContext *ctx, AVCodecContext *avctx)
 
 
 /**
- *  Decodes Indeo5 band header.
+ *  Decode Indeo5 band header.
  *
- *  @param ctx      [in,out] ptr to the decoder context
- *  @param band     [in,out] ptr to the band descriptor
- *  @param avctx    [in] ptr to the AVCodecContext
+ *  @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_hdr(IVI5DecContext *ctx, IVIBandDesc *band,
@@ -414,13 +432,13 @@ static int decode_band_hdr(IVI5DecContext *ctx, IVIBandDesc *band,
 
 
 /**
- *  Decodes info (block type, cbp, quant delta, motion vector)
+ *  Decode info (block type, cbp, quant delta, motion vector)
  *  for all macroblocks in the current tile.
  *
- *  @param ctx      [in,out] ptr to the decoder context
- *  @param band     [in,out] ptr to the band descriptor
- *  @param tile     [in,out] ptr to the tile descriptor
- *  @param avctx    [in] ptr to the AVCodecContext
+ *  @param[in,out]  ctx    ptr to the decoder context
+ *  @param[in,out]  band   ptr to the band descriptor
+ *  @param[in,out]  tile   ptr to the tile descriptor
+ *  @param[in]      avctx  ptr to the AVCodecContext
  *  @return         result code: 0 = OK, -1 = error
  */
 static int decode_mb_info(IVI5DecContext *ctx, IVIBandDesc *band,
@@ -539,17 +557,17 @@ static int decode_mb_info(IVI5DecContext *ctx, IVIBandDesc *band,
 
 
 /**
- *  Decodes an Indeo5 band.
+ *  Decode an Indeo5 band.
  *
- *  @param ctx      [in,out] ptr to the decoder context
- *  @param band     [in,out] ptr to the band descriptor
- *  @param avctx    [in] ptr to the AVCodecContext
+ *  @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(IVI5DecContext *ctx, int plane_num,
                        IVIBandDesc *band, AVCodecContext *avctx)
 {
-    int         result, i, t, idx1, idx2;
+    int         result, i, t, idx1, idx2, pos;
     IVITile     *tile;
 
     band->buf     = band->bufs[ctx->dst_buf];
@@ -578,6 +596,8 @@ static int decode_band(IVI5DecContext *ctx, int plane_num,
         FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]);
     }
 
+    pos = get_bits_count(&ctx->gb);
+
     for (t = 0; t < band->num_tiles; t++) {
         tile = &band->tiles[t];
 
@@ -585,7 +605,6 @@ static int decode_band(IVI5DecContext *ctx, int plane_num,
         if (tile->is_empty) {
             ff_ivi_process_empty_tile(avctx, band, tile,
                                       (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3));
-            align_get_bits(&ctx->gb);
         } else {
             tile->data_size = ff_ivi_dec_tile_data_size(&ctx->gb);
 
@@ -593,23 +612,12 @@ static int decode_band(IVI5DecContext *ctx, int plane_num,
             if (result < 0)
                 break;
 
-            if (band->blk_size == 8) {
-                band->intra_base  = &ivi5_base_quant_8x8_intra[band->quant_mat][0];
-                band->inter_base  = &ivi5_base_quant_8x8_inter[band->quant_mat][0];
-                band->intra_scale = &ivi5_scale_quant_8x8_intra[band->quant_mat][0];
-                band->inter_scale = &ivi5_scale_quant_8x8_inter[band->quant_mat][0];
-            } else {
-                band->intra_base  = ivi5_base_quant_4x4_intra;
-                band->inter_base  = ivi5_base_quant_4x4_inter;
-                band->intra_scale = ivi5_scale_quant_4x4_intra;
-                band->inter_scale = ivi5_scale_quant_4x4_inter;
-            }
-
             result = ff_ivi_decode_blocks(&ctx->gb, band, tile);
-            if (result < 0) {
-                av_log(avctx, AV_LOG_ERROR, "Corrupted blocks data encountered!\n");
+            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
         }
     }
 
@@ -621,7 +629,7 @@ static int decode_band(IVI5DecContext *ctx, int plane_num,
         FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]);
     }
 
-#if IVI_DEBUG
+#ifdef DEBUG
     if (band->checksum_present) {
         uint16_t chksum = ivi_calc_band_checksum(band);
         if (chksum != band->checksum) {
@@ -632,71 +640,57 @@ static int decode_band(IVI5DecContext *ctx, int plane_num,
     }
 #endif
 
+    align_get_bits(&ctx->gb);
+
     return result;
 }
 
 
 /**
- *  Switches buffers.
+ *  Switch buffers.
  *
- *  @param ctx      [in,out] ptr to the decoder context
- *  @param avctx    [in] ptr to the AVCodecContext
+ *  @param[in,out] ctx  ptr to the decoder context
  */
-static void switch_buffers(IVI5DecContext *ctx, AVCodecContext *avctx)
+static void switch_buffers(IVI5DecContext *ctx)
 {
-    switch (ctx->frame_type) {
+    switch (ctx->prev_frame_type) {
     case FRAMETYPE_INTRA:
-        ctx->buf_switch = 0;
-        ctx->dst_buf    = 0;
-        ctx->ref_buf    = 0;
-        break;
     case FRAMETYPE_INTER:
-        ctx->buf_switch &= 1;
-        /* swap buffers only if there were no droppable frames */
-        if (ctx->prev_frame_type != FRAMETYPE_INTER_NOREF &&
-            ctx->prev_frame_type != FRAMETYPE_INTER_SCAL)
-            ctx->buf_switch ^= 1;
+        ctx->buf_switch ^= 1;
         ctx->dst_buf = ctx->buf_switch;
         ctx->ref_buf = ctx->buf_switch ^ 1;
         break;
     case FRAMETYPE_INTER_SCAL:
-        if (ctx->prev_frame_type == FRAMETYPE_INTER_NOREF)
-            break;
-        if (ctx->prev_frame_type != FRAMETYPE_INTER_SCAL) {
-            ctx->buf_switch ^= 1;
-            ctx->dst_buf     = ctx->buf_switch;
-            ctx->ref_buf     = ctx->buf_switch ^ 1;
-        } else {
-            ctx->buf_switch ^= 2;
-            ctx->dst_buf = 2;
-            ctx->ref_buf = ctx->buf_switch & 1;
-            if (!(ctx->buf_switch & 2))
-                FFSWAP(int, ctx->dst_buf, ctx->ref_buf);
+        if (!ctx->inter_scal) {
+            ctx->ref2_buf   = 2;
+            ctx->inter_scal = 1;
         }
+        FFSWAP(int, ctx->dst_buf, ctx->ref2_buf);
+        ctx->ref_buf = ctx->ref2_buf;
         break;
     case FRAMETYPE_INTER_NOREF:
-        if (ctx->prev_frame_type == FRAMETYPE_INTER_SCAL) {
-            ctx->buf_switch ^= 2;
-            ctx->dst_buf = 2;
-            ctx->ref_buf = ctx->buf_switch & 1;
-            if (!(ctx->buf_switch & 2))
-                FFSWAP(int, ctx->dst_buf, ctx->ref_buf);
-        } else {
-            ctx->buf_switch ^= 1;
-            ctx->dst_buf     =  ctx->buf_switch & 1;
-            ctx->ref_buf     = (ctx->buf_switch & 1) ^ 1;
-        }
         break;
+    }
+
+    switch (ctx->frame_type) {
+    case FRAMETYPE_INTRA:
+        ctx->buf_switch = 0;
+        /* FALLTHROUGH */
+    case FRAMETYPE_INTER:
+        ctx->inter_scal = 0;
+        ctx->dst_buf = ctx->buf_switch;
+        ctx->ref_buf = ctx->buf_switch ^ 1;
+        break;
+    case FRAMETYPE_INTER_SCAL:
+    case FRAMETYPE_INTER_NOREF:
     case FRAMETYPE_NULL:
-        return;
-    default:
-        av_log(avctx, AV_LOG_ERROR, "unsupported frame type: %d\n", ctx->frame_type);
+        break;
     }
 }
 
 
 /**
- *  Initializes Indeo5 decoder.
+ *  Initialize Indeo5 decoder.
  */
 static av_cold int decode_init(AVCodecContext *avctx)
 {
@@ -725,6 +719,9 @@ static av_cold int decode_init(AVCodecContext *avctx)
         return -1;
     }
 
+    ctx->buf_switch = 0;
+    ctx->inter_scal = 0;
+
     avctx->pix_fmt = PIX_FMT_YUV410P;
 
     return 0;
@@ -758,13 +755,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
         return -1;
     }
 
-    switch_buffers(ctx, avctx);
+    switch_buffers(ctx);
 
     //START_TIMER;
 
-    if (ctx->frame_type == FRAMETYPE_NULL) {
-        ctx->frame_type = ctx->prev_frame_type;
-    } else {
+    if (ctx->frame_type != FRAMETYPE_NULL) {
         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);
@@ -805,7 +800,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
 
 
 /**
- *  Closes Indeo5 decoder and cleans up its context.
+ *  Close Indeo5 decoder and clean up its context.
  */
 static av_cold int decode_close(AVCodecContext *avctx)
 {
@@ -823,9 +818,9 @@ static av_cold int decode_close(AVCodecContext *avctx)
 }
 
 
-AVCodec indeo5_decoder = {
+AVCodec ff_indeo5_decoder = {
     .name           = "indeo5",
-    .type           = CODEC_TYPE_VIDEO,
+    .type           = AVMEDIA_TYPE_VIDEO,
     .id             = CODEC_ID_INDEO5,
     .priv_data_size = sizeof(IVI5DecContext),
     .init           = decode_init,