Commit 349c6241 authored by Michael Niedermayer's avatar Michael Niedermayer

Merge remote-tracking branch 'qatar/master'

* 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: 's avatarMichael Niedermayer <michaelni@gmx.at>
parents 432fe9a3 4f04f5cc
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
* @file * @file
* IMC - Intel Music Coder * IMC - Intel Music Coder
* A mdct based codec using a 256 points large transform * A mdct based codec using a 256 points large transform
* divied into 32 bands with some mix of scale factors. * divided into 32 bands with some mix of scale factors.
* Only mono is supported. * Only mono is supported.
* *
*/ */
......
...@@ -35,9 +35,6 @@ ...@@ -35,9 +35,6 @@
#include "ivi_common.h" #include "ivi_common.h"
#include "indeo4data.h" #include "indeo4data.h"
#define IVI4_STREAM_ANALYSER 0
#define IVI4_DEBUG_CHECKSUM 0
/** /**
* Indeo 4 frame types. * Indeo 4 frame types.
*/ */
...@@ -54,46 +51,6 @@ enum { ...@@ -54,46 +51,6 @@ enum {
#define IVI4_PIC_SIZE_ESC 7 #define IVI4_PIC_SIZE_ESC 7
typedef struct {
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
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
IVIHuffTab mb_vlc; ///< current macroblock table descriptor
IVIHuffTab blk_vlc; ///< current block table descriptor
uint16_t checksum; ///< frame checksum
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;
#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
} IVI4DecContext;
static const struct { static const struct {
InvTransformPtr *inv_trans; InvTransformPtr *inv_trans;
DCTransformPtr *dc_trans; DCTransformPtr *dc_trans;
...@@ -158,7 +115,7 @@ static inline int scale_tile_size(int def_size, int size_factor) ...@@ -158,7 +115,7 @@ static inline int scale_tile_size(int def_size, int size_factor)
* @param[in] avctx pointer to the AVCodecContext * @param[in] avctx pointer to the AVCodecContext
* @return result code: 0 = OK, negative number = error * @return result code: 0 = OK, negative number = error
*/ */
static int decode_pic_hdr(IVI4DecContext *ctx, AVCodecContext *avctx) static int decode_pic_hdr(IVI45DecContext *ctx, AVCodecContext *avctx)
{ {
int pic_size_indx, i, p; int pic_size_indx, i, p;
IVIPicConfig pic_conf; IVIPicConfig pic_conf;
...@@ -322,7 +279,7 @@ static int decode_pic_hdr(IVI4DecContext *ctx, AVCodecContext *avctx) ...@@ -322,7 +279,7 @@ static int decode_pic_hdr(IVI4DecContext *ctx, AVCodecContext *avctx)
* @param[in] avctx pointer to the AVCodecContext * @param[in] avctx pointer to the AVCodecContext
* @return result code: 0 = OK, negative number = error * @return result code: 0 = OK, negative number = error
*/ */
static int decode_band_hdr(IVI4DecContext *ctx, IVIBandDesc *band, static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band,
AVCodecContext *avctx) AVCodecContext *avctx)
{ {
int plane, band_num, indx, transform_id, scan_indx; int plane, band_num, indx, transform_id, scan_indx;
...@@ -482,7 +439,7 @@ static int decode_band_hdr(IVI4DecContext *ctx, IVIBandDesc *band, ...@@ -482,7 +439,7 @@ static int decode_band_hdr(IVI4DecContext *ctx, IVIBandDesc *band,
* @param[in] avctx pointer to the AVCodecContext * @param[in] avctx pointer to the AVCodecContext
* @return result code: 0 = OK, negative number = error * @return result code: 0 = OK, negative number = error
*/ */
static int decode_mb_info(IVI4DecContext *ctx, IVIBandDesc *band, static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band,
IVITile *tile, AVCodecContext *avctx) IVITile *tile, AVCodecContext *avctx)
{ {
int x, y, mv_x, mv_y, mv_delta, offs, mb_offset, blks_per_mb, int x, y, mv_x, mv_y, mv_delta, offs, mb_offset, blks_per_mb,
...@@ -611,136 +568,12 @@ static int decode_mb_info(IVI4DecContext *ctx, IVIBandDesc *band, ...@@ -611,136 +568,12 @@ static int decode_mb_info(IVI4DecContext *ctx, IVIBandDesc *band,
} }
/**
* Decode an Indeo 4 band.
*
* @param[in,out] ctx pointer to the decoder context
* @param[in,out] band pointer to the band descriptor
* @param[in] avctx pointer to the AVCodecContext
* @return result code: 0 = OK, negative number = error
*/
static int decode_band(IVI4DecContext *ctx, int plane_num,
IVIBandDesc *band, AVCodecContext *avctx)
{
int result, i, t, pos, idx1, idx2;
IVITile *tile;
int ret = 0;
band->buf = band->bufs[ctx->dst_buf];
band->ref_buf = band->bufs[ctx->ref_buf];
result = decode_band_hdr(ctx, band, avctx);
if (result) {
av_log(avctx, AV_LOG_ERROR, "Error decoding band header\n");
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];
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");
ret = AVERROR_INVALIDDATA;
break;
}
result = 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;
}
#if defined(DEBUG) && IVI4_DEBUG_CHECKSUM
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 ret;
}
static av_cold int decode_init(AVCodecContext *avctx)
{
IVI4DecContext *ctx = avctx->priv_data;
ff_ivi_init_static_vlc();
/* copy rvmap tables in our context so we can apply changes to them */
memcpy(ctx->rvmap_tabs, ff_ivi_rvmap_tabs, sizeof(ff_ivi_rvmap_tabs));
/* Force allocation of the internal buffers */
/* during picture header decoding. */
ctx->pic_conf.pic_width = 0;
ctx->pic_conf.pic_height = 0;
avctx->pix_fmt = PIX_FMT_YUV410P;
return 0;
}
/** /**
* Rearrange decoding and reference buffers. * Rearrange decoding and reference buffers.
* *
* @param[in,out] ctx pointer to the decoder context * @param[in,out] ctx pointer to the decoder context
*/ */
static void switch_buffers(IVI4DecContext *ctx) static void switch_buffers(IVI45DecContext *ctx)
{ {
switch (ctx->prev_frame_type) { switch (ctx->prev_frame_type) {
case FRAMETYPE_INTRA: case FRAMETYPE_INTRA:
...@@ -769,99 +602,33 @@ static void switch_buffers(IVI4DecContext *ctx) ...@@ -769,99 +602,33 @@ static void switch_buffers(IVI4DecContext *ctx)
} }
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, static int is_nonnull_frame(IVI45DecContext *ctx)
AVPacket *avpkt)
{ {
IVI4DecContext *ctx = avctx->priv_data; return ctx->frame_type < FRAMETYPE_NULL_FIRST;
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
int result, p, b;
init_get_bits(&ctx->gb, buf, buf_size * 8);
result = decode_pic_hdr(ctx, avctx);
if (result) {
av_log(avctx, AV_LOG_ERROR, "Error decoding picture header\n");
return result;
}
switch_buffers(ctx);
if (ctx->frame_type < FRAMETYPE_NULL_FIRST) {
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 decoding band: %d, plane: %d\n", b, p);
return result;
}
}
}
}
/* 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 (ctx->frame_type == 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 (ctx->frame_type >= FRAMETYPE_NULL_FIRST)
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) {
ff_ivi_recompose_haar(&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;
} }
static av_cold int decode_close(AVCodecContext *avctx) static av_cold int decode_init(AVCodecContext *avctx)
{ {
IVI4DecContext *ctx = avctx->priv_data; IVI45DecContext *ctx = avctx->priv_data;
ff_ivi_free_buffers(&ctx->planes[0]); ff_ivi_init_static_vlc();
if (ctx->frame.data[0]) /* copy rvmap tables in our context so we can apply changes to them */
avctx->release_buffer(avctx, &ctx->frame); memcpy(ctx->rvmap_tabs, ff_ivi_rvmap_tabs, sizeof(ff_ivi_rvmap_tabs));
#if IVI4_STREAM_ANALYSER /* Force allocation of the internal buffers */
if (ctx->is_scalable) /* during picture header decoding. */
av_log(avctx, AV_LOG_ERROR, "This video uses scalability mode!\n"); ctx->pic_conf.pic_width = 0;
if (ctx->uses_tiling) ctx->pic_conf.pic_height = 0;
av_log(avctx, AV_LOG_ERROR, "This video uses local decoding!\n");
if (ctx->has_b_frames) avctx->pix_fmt = PIX_FMT_YUV410P;
av_log(avctx, AV_LOG_ERROR, "This video contains B-frames!\n");
if (ctx->has_transp) ctx->decode_pic_hdr = decode_pic_hdr;
av_log(avctx, AV_LOG_ERROR, "Transparency mode is enabled!\n"); ctx->decode_band_hdr = decode_band_hdr;
if (ctx->uses_haar) ctx->decode_mb_info = decode_mb_info;
av_log(avctx, AV_LOG_ERROR, "This video uses Haar transform!\n"); ctx->switch_buffers = switch_buffers;
if (ctx->uses_fullpel) ctx->is_nonnull_frame = is_nonnull_frame;
av_log(avctx, AV_LOG_ERROR, "This video uses fullpel motion vectors!\n");
#endif
return 0; return 0;
} }
...@@ -871,9 +638,9 @@ AVCodec ff_indeo4_decoder = { ...@@ -871,9 +638,9 @@ AVCodec ff_indeo4_decoder = {
.name = "indeo4", .name = "indeo4",
.type = AVMEDIA_TYPE_VIDEO, .type = AVMEDIA_TYPE_VIDEO,
.id = CODEC_ID_INDEO4, .id = CODEC_ID_INDEO4,
.priv_data_size = sizeof(IVI4DecContext), .priv_data_size = sizeof(IVI45DecContext),
.init = decode_init, .init = decode_init,
.close = decode_close, .close = ff_ivi_decode_close,
.decode = decode_frame, .decode = ff_ivi_decode_frame,
.long_name = NULL_IF_CONFIG_SMALL("Intel Indeo Video Interactive 4"), .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo Video Interactive 4"),
}; };
...@@ -48,40 +48,6 @@ enum { ...@@ -48,40 +48,6 @@ enum {
#define IVI5_PIC_SIZE_ESC 15 #define IVI5_PIC_SIZE_ESC 15
#define IVI5_IS_PROTECTED 0x20
typedef struct {
GetBitContext gb;
AVFrame frame;
RVMapDesc rvmap_tabs[9]; ///< local corrected copy of the static rvmap tables
IVIPlaneDesc planes[3]; ///< color planes
const uint8_t *frame_data; ///< input frame data pointer
int buf_switch; ///< used to switch between three buffers
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
int frame_num;
uint32_t pic_hdr_size; ///< picture header size in bytes
uint8_t frame_flags;
uint16_t checksum; ///< frame checksum
IVIHuffTab mb_vlc; ///< vlc table for decoding macroblock data
uint16_t gop_hdr_size;
uint8_t gop_flags;
int is_scalable;
uint32_t lock_word;
IVIPicConfig pic_conf;
int gop_invalid;
int buf_invalid[3];
} IVI5DecContext;
/** /**
* Decode Indeo5 GOP (Group of pictures) header. * Decode Indeo5 GOP (Group of pictures) header.
* This header is present in key frames only. * This header is present in key frames only.
...@@ -91,7 +57,7 @@ typedef struct { ...@@ -91,7 +57,7 @@ typedef struct {
* @param[in] avctx ptr to the AVCodecContext * @param[in] avctx ptr to the AVCodecContext
* @return result code: 0 = OK, -1 = error * @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, is_scalable; int result, i, p, tile_size, pic_size_indx, mb_size, blk_size, is_scalable;
int quant_mat, blk_size_changed = 0; int quant_mat, blk_size_changed = 0;
...@@ -333,7 +299,7 @@ static inline void skip_hdr_extension(GetBitContext *gb) ...@@ -333,7 +299,7 @@ static inline void skip_hdr_extension(GetBitContext *gb)
* @param[in] avctx ptr to the AVCodecContext * @param[in] avctx ptr to the AVCodecContext
* @return result code: 0 = OK, -1 = error * @return result code: 0 = OK, -1 = error
*/ */
static int decode_pic_hdr(IVI5DecContext *ctx, AVCodecContext *avctx) static int decode_pic_hdr(IVI45DecContext *ctx, AVCodecContext *avctx)
{ {
if (get_bits(&ctx->gb, 5) != 0x1F) { if (get_bits(&ctx->gb, 5) != 0x1F) {
av_log(avctx, AV_LOG_ERROR, "Invalid picture start code!\n"); av_log(avctx, AV_LOG_ERROR, "Invalid picture start code!\n");
...@@ -394,7 +360,7 @@ static int decode_pic_hdr(IVI5DecContext *ctx, AVCodecContext *avctx) ...@@ -394,7 +360,7 @@ static int decode_pic_hdr(IVI5DecContext *ctx, AVCodecContext *avctx)
* @param[in] avctx ptr to the AVCodecContext * @param[in] avctx ptr to the AVCodecContext
* @return result code: 0 = OK, -1 = error * @return result code: 0 = OK, -1 = error
*/ */
static int decode_band_hdr(IVI5DecContext *ctx, IVIBandDesc *band, static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band,
AVCodecContext *avctx) AVCodecContext *avctx)
{ {
int i; int i;
...@@ -464,7 +430,7 @@ static int decode_band_hdr(IVI5DecContext *ctx, IVIBandDesc *band, ...@@ -464,7 +430,7 @@ static int decode_band_hdr(IVI5DecContext *ctx, IVIBandDesc *band,
* @param[in] avctx ptr to the AVCodecContext * @param[in] avctx ptr to the AVCodecContext
* @return result code: 0 = OK, -1 = error * @return result code: 0 = OK, -1 = error
*/ */
static int decode_mb_info(IVI5DecContext *ctx, IVIBandDesc *band, static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band,
IVITile *tile, AVCodecContext *avctx) IVITile *tile, AVCodecContext *avctx)
{ {
int x, y, mv_x, mv_y, mv_delta, offs, mb_offset, int x, y, mv_x, mv_y, mv_delta, offs, mb_offset,
...@@ -598,102 +564,12 @@ static int decode_mb_info(IVI5DecContext *ctx, IVIBandDesc *band, ...@@ -598,102 +564,12 @@ static int decode_mb_info(IVI5DecContext *ctx, IVIBandDesc *band,
} }
/**
* Decode an Indeo5 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(IVI5DecContext *ctx, int plane_num,
IVIBandDesc *band, AVCodecContext *avctx)
{
int result, i, t, idx1, idx2, pos;
IVITile *tile;
band->buf = band->bufs[ctx->dst_buf];
band->ref_buf = band->bufs[ctx->ref_buf];
band->data_ptr = ctx->frame_data + (get_bits_count(&ctx->gb) >> 3);
result = decode_band_hdr(ctx, band, avctx);
if (result) {
av_log(avctx, AV_LOG_ERROR, "Error while decoding band header: %d\n",
result);
return -1;
}
if (band->is_empty) {
av_log(avctx, AV_LOG_ERROR, "Empty band encountered!\n");
return -1;
}
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]);
}
pos = get_bits_count(&ctx->gb);
for (t = 0; t < band->num_tiles; t++) {
tile = &band->tiles[t];
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));
} else {
tile->data_size = ff_ivi_dec_tile_data_size(&ctx->gb);
result = 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]);
}
#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;
}
/** /**
* Switch buffers. * Switch buffers.
* *
* @param[in,out] ctx ptr to the decoder context * @param[in,out] ctx ptr to the decoder context
*/ */
static void switch_buffers(IVI5DecContext *ctx) static void switch_buffers(IVI45DecContext *ctx)
{ {
switch (ctx->prev_frame_type) { switch (ctx->prev_frame_type) {
case FRAMETYPE_INTRA: case FRAMETYPE_INTRA:
...@@ -731,12 +607,18 @@ static void switch_buffers(IVI5DecContext *ctx) ...@@ -731,12 +607,18 @@ static void switch_buffers(IVI5DecContext *ctx)
} }
static int is_nonnull_frame(IVI45DecContext *ctx)
{
return ctx->frame_type != FRAMETYPE_NULL;
}
/** /**
* Initialize Indeo5 decoder. * Initialize Indeo5 decoder.
*/ */
static av_cold int decode_init(AVCodecContext *avctx) static av_cold int decode_init(AVCodecContext *avctx)
{ {
IVI5DecContext *ctx = avctx->priv_data; IVI45DecContext *ctx = avctx->priv_data;
int result; int result;
ff_ivi_init_static_vlc(); ff_ivi_init_static_vlc();
...@@ -766,117 +648,24 @@ static av_cold int decode_init(AVCodecContext *avctx) ...@@ -766,117 +648,24 @@ static av_cold int decode_init(AVCodecContext *avctx)
ctx->buf_switch = 0; ctx->buf_switch = 0;
ctx->inter_scal = 0; ctx->inter_scal = 0;
avctx->pix_fmt = PIX_FMT_YUV410P; ctx->decode_pic_hdr = decode_pic_hdr;
ctx->decode_band_hdr = decode_band_hdr;
return 0; ctx->decode_mb_info = decode_mb_info;
} ctx->switch_buffers = switch_buffers;
ctx->is_nonnull_frame = is_nonnull_frame;
/**
* main decoder function
*/
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
AVPacket *avpkt)
{
IVI5DecContext *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 = 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;
}
switch_buffers(ctx);
//{ START_TIMER;
if (ctx->frame_type != FRAMETYPE_NULL) { avctx->pix_fmt = PIX_FMT_YUV410P;
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 (ctx->frame.data[0])
avctx->release_buffer(avctx, &ctx->frame);
if( avctx->width != ctx->planes[0].width
|| avctx->height != ctx->planes[0].height)
avcodec_set_dimensions(avctx, ctx->planes[0].width, ctx->planes[0].height);
ctx->frame.reference = 0;
if (avctx->get_buffer(avctx, &ctx->frame) < 0) {
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return -1;
}
if (ctx->is_scalable) {
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.
*/
static av_cold int decode_close(AVCodecContext *avctx)
{
IVI5DecContext *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);
return 0; return 0;
} }
AVCodec ff_indeo5_decoder = { AVCodec ff_indeo5_decoder = {
.name = "indeo5", .name = "indeo5",
.type = AVMEDIA_TYPE_VIDEO, .type = AVMEDIA_TYPE_VIDEO,
.id = CODEC_ID_INDEO5, .id = CODEC_ID_INDEO5,
.priv_data_size = sizeof(IVI5DecContext), .priv_data_size = sizeof(IVI45DecContext),
.init = decode_init, .init = decode_init,
.close = decode_close, .close = ff_ivi_decode_close,
.decode = decode_frame, .decode = ff_ivi_decode_frame,
.long_name = NULL_IF_CONFIG_SMALL("Intel Indeo Video Interactive 5"), .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo Video Interactive 5"),
}; };
...@@ -123,6 +123,10 @@ int ff_ivi_dec_huff_desc(GetBitContext *gb, int desc_coded, int which_tab, ...@@ -123,6 +123,10 @@ int ff_ivi_dec_huff_desc(GetBitContext *gb, int desc_coded, int which_tab,
if (huff_tab->tab_sel == 7) { if (huff_tab->tab_sel == 7) {
/* custom huffman table (explicitly encoded) */ /* custom huffman table (explicitly encoded) */
new_huff.num_rows = get_bits(gb, 4); new_huff.num_rows = get_bits(gb, 4);
if (!new_huff.num_rows) {
av_log(avctx, AV_LOG_ERROR, "Empty custom Huffman table!\n");
return AVERROR_INVALIDDATA;
}
for (i = 0; i < new_huff.num_rows; i++) for (i = 0; i < new_huff.num_rows; i++)
new_huff.xbits[i] = get_bits(gb, 4); new_huff.xbits[i] = get_bits(gb, 4);
...@@ -136,9 +140,10 @@ int ff_ivi_dec_huff_desc(GetBitContext *gb, int desc_coded, int which_tab, ...@@ -136,9 +140,10 @@ int ff_ivi_dec_huff_desc(GetBitContext *gb, int desc_coded, int which_tab,
result = ff_ivi_create_huff_from_desc(&huff_tab->cust_desc, result = ff_ivi_create_huff_from_desc(&huff_tab->cust_desc,
&huff_tab->cust_tab, 0); &huff_tab->cust_tab, 0);
if (result) { if (result) {
huff_tab->cust_desc.num_rows = 0; // reset faulty description
av_log(avctx, AV_LOG_ERROR, av_log(avctx, AV_LOG_ERROR,
"Error while initializing custom vlc table!\n"); "Error while initializing custom vlc table!\n");
return -1; return result;
} }
} }
huff_tab->tab = &huff_tab->cust_tab; huff_tab->tab = &huff_tab->cust_tab;
...@@ -207,15 +212,16 @@ av_cold int ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg) ...@@ -207,15 +212,16 @@ av_cold int ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg)
band->width = b_width; band->width = b_width;
band->height = b_height; band->height = b_height;
band->pitch = width_aligned; band->pitch = width_aligned;
band->bufs[0] = av_malloc(buf_size); band->aheight = height_aligned;
band->bufs[1] = av_malloc(buf_size); band->bufs[0] = av_mallocz(buf_size);
band->bufs[1] = av_mallocz(buf_size);
band->bufsize = buf_size/2; band->bufsize = buf_size/2;
if (!band->bufs[0] || !band->bufs[1]) if (!band->bufs[0] || !band->bufs[1])
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
/* allocate the 3rd band buffer for scalability mode */ /* allocate the 3rd band buffer for scalability mode */
if (cfg->luma_bands > 1) { if (cfg->luma_bands > 1) {
band->bufs[2] = av_malloc(buf_size); band->bufs[2] = av_mallocz(buf_size);
if (!band->bufs[2]) if (!band->bufs[2])
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
} }
...@@ -285,6 +291,7 @@ av_cold int ff_ivi_init_tiles(IVIPlaneDesc *planes, int tile_width, int tile_hei ...@@ -285,6 +291,7 @@ av_cold int ff_ivi_init_tiles(IVIPlaneDesc *planes, int tile_width, int tile_hei
for (x = 0; x < band->width; x += t_width) { for (x = 0; x < band->width; x += t_width) {
tile->xpos = x; tile->xpos = x;
tile->ypos = y; tile->ypos = y;
tile->mb_size = band->mb_size;
tile->width = FFMIN(band->width - x, t_width); tile->width = FFMIN(band->width - x, t_width);
tile->height = FFMIN(band->height - y, t_height); tile->height = FFMIN(band->height - y, t_height);
tile->is_empty = tile->data_size = 0; tile->is_empty = tile->data_size = 0;
...@@ -378,6 +385,21 @@ int ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile) ...@@ -378,6 +385,21 @@ int ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile)
mv_x >>= 1; mv_x >>= 1;
mv_y >>= 1; /* convert halfpel vectors into fullpel ones */ mv_y >>= 1; /* convert halfpel vectors into fullpel ones */
} }
if (mb->type) {
int dmv_x, dmv_y, cx, cy;
dmv_x = mb->mv_x >> band->is_halfpel;
dmv_y = mb->mv_y >> band->is_halfpel;
cx = mb->mv_x & band->is_halfpel;
cy = mb->mv_y & band->is_halfpel;
if ( mb->xpos + dmv_x < 0
|| mb->xpos + dmv_x + band->mb_size + cx > band->pitch
|| mb->ypos + dmv_y < 0
|| mb->ypos + dmv_y + band->mb_size + cy > band->aheight) {
return AVERROR_INVALIDDATA;
}
}
} }
for (blk = 0; blk < num_blocks; blk++) { for (blk = 0; blk < num_blocks; blk++) {
...@@ -574,7 +596,7 @@ void ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, ...@@ -574,7 +596,7 @@ void ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band,
#ifdef DEBUG #ifdef DEBUG
uint16_t ivi_calc_band_checksum (IVIBandDesc *band) static uint16_t ivi_calc_band_checksum(IVIBandDesc *band)
{ {
int x, y; int x, y;
int16_t *src, checksum; int16_t *src, checksum;
...@@ -588,31 +610,6 @@ uint16_t ivi_calc_band_checksum (IVIBandDesc *band) ...@@ -588,31 +610,6 @@ uint16_t ivi_calc_band_checksum (IVIBandDesc *band)
return checksum; return checksum;
} }
int ivi_check_band (IVIBandDesc *band, const uint8_t *ref, int pitch)
{
int x, y, result;
uint8_t t1, t2;
int16_t *src;
src = band->buf;
result = 0;
for (y = 0; y < band->height; src += band->pitch, y++) {
for (x = 0; x < band->width; x++) {
t1 = av_clip(src[x] + 128, 0, 255);
t2 = ref[x];
if (t1 != t2) {
av_log(NULL, AV_LOG_ERROR, "Data mismatch: row %d, column %d\n",
y / band->blk_size, x / band->blk_size);
result = -1;
}
}
ref += pitch;
}
return result;
}
#endif #endif
void ff_ivi_output_plane(IVIPlaneDesc *plane, uint8_t *dst, int dst_pitch) void ff_ivi_output_plane(IVIPlaneDesc *plane, uint8_t *dst, int dst_pitch)
...@@ -632,6 +629,242 @@ void ff_ivi_output_plane(IVIPlaneDesc *plane, uint8_t *dst, int dst_pitch) ...@@ -632,6 +629,242 @@ void ff_ivi_output_plane(IVIPlaneDesc *plane, uint8_t *dst, int dst_pitch)
} }
} }
/**
* 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");
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 * These are 2x8 predefined Huffman codebooks for coding macroblock/block
......
...@@ -34,6 +34,8 @@ ...@@ -34,6 +34,8 @@
#include <stdint.h> #include <stdint.h>
#define IVI_VLC_BITS 13 ///< max number of bits of the ivi's huffman codes #define IVI_VLC_BITS 13 ///< max number of bits of the ivi's huffman codes
#define IVI4_STREAM_ANALYSER 0
#define IVI5_IS_PROTECTED 0x20
/** /**
* huffman codebook descriptor * huffman codebook descriptor
...@@ -116,6 +118,7 @@ typedef struct { ...@@ -116,6 +118,7 @@ typedef struct {
int ypos; int ypos;
int width; int width;
int height; int height;
int mb_size;
int is_empty; ///< = 1 if this tile doesn't contain any data int is_empty; ///< = 1 if this tile doesn't contain any data
int data_size; ///< size of the data in bytes int data_size; ///< size of the data in bytes
int num_MBs; ///< number of macroblocks in this tile int num_MBs; ///< number of macroblocks in this tile
...@@ -132,6 +135,7 @@ typedef struct { ...@@ -132,6 +135,7 @@ typedef struct {
int band_num; ///< band number int band_num; ///< band number
int width; int width;
int height; int height;
int aheight; ///< aligned band height
const uint8_t *data_ptr; ///< ptr to the first byte of the band data const uint8_t *data_ptr; ///< ptr to the first byte of the band data
int data_size; ///< size of the band data int data_size; ///< size of the band data
int16_t *buf; ///< pointer to the output buffer for this band int16_t *buf; ///< pointer to the output buffer for this band
...@@ -193,6 +197,63 @@ typedef struct { ...@@ -193,6 +197,63 @@ typedef struct {
uint8_t chroma_bands; uint8_t chroma_bands;
} IVIPicConfig; } 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 */ /** compare some properties of two pictures */
static inline int ivi_pic_config_cmp(IVIPicConfig *str1, IVIPicConfig *str2) static inline int ivi_pic_config_cmp(IVIPicConfig *str1, IVIPicConfig *str2)
{ {
...@@ -339,14 +400,8 @@ void ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, ...@@ -339,14 +400,8 @@ void ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band,
*/ */
void ff_ivi_output_plane(IVIPlaneDesc *plane, uint8_t *dst, int dst_pitch); void ff_ivi_output_plane(IVIPlaneDesc *plane, uint8_t *dst, int dst_pitch);
/** int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
* Calculate band checksum from band data. AVPacket *avpkt);
*/ av_cold int ff_ivi_decode_close(AVCodecContext *avctx);
uint16_t ivi_calc_band_checksum (IVIBandDesc *band);
/**
* Verify that band data lies in range.
*/
int ivi_check_band (IVIBandDesc *band, const uint8_t *ref, int pitch);
#endif /* AVCODEC_IVI_COMMON_H */ #endif /* AVCODEC_IVI_COMMON_H */
...@@ -174,9 +174,12 @@ static void ff_region_offset2size(GranuleDef *g) ...@@ -174,9 +174,12 @@ static void ff_region_offset2size(GranuleDef *g)
static void ff_init_short_region(MPADecodeContext *s, GranuleDef *g) static void ff_init_short_region(MPADecodeContext *s, GranuleDef *g)
{ {
if (g->block_type == 2) if (g->block_type == 2) {
g->region_size[0] = (36 / 2); if (s->sample_rate_index != 8)
else { g->region_size[0] = (36 / 2);
else
g->region_size[0] = (72 / 2);
} else {
if (s->sample_rate_index <= 2) if (s->sample_rate_index <= 2)
g->region_size[0] = (36 / 2); g->region_size[0] = (36 / 2);
else if (s->sample_rate_index != 8) else if (s->sample_rate_index != 8)
...@@ -201,14 +204,12 @@ static void ff_compute_band_indexes(MPADecodeContext *s, GranuleDef *g) ...@@ -201,14 +204,12 @@ static void ff_compute_band_indexes(MPADecodeContext *s, GranuleDef *g)
if (g->block_type == 2) { if (g->block_type == 2) {
if (g->switch_point) { if (g->switch_point) {
/* if switched mode, we handle the 36 first samples as /* if switched mode, we handle the 36 first samples as
long blocks. For 8000Hz, we handle the 48 first long blocks. For 8000Hz, we handle the 72 first
exponents as long blocks (XXX: check this!) */ exponents as long blocks */
if (s->sample_rate_index <= 2) if (s->sample_rate_index <= 2)
g->long_end = 8; g->long_end = 8;
else if (s->sample_rate_index != 8)
g->long_end = 6;
else else
g->long_end = 4; /* 8000 Hz */ g->long_end = 6;
g->short_start = 2 + (s->sample_rate_index != 8); g->short_start = 2 + (s->sample_rate_index != 8);
} else { } else {
...@@ -1018,7 +1019,7 @@ static void reorder_block(MPADecodeContext *s, GranuleDef *g) ...@@ -1018,7 +1019,7 @@ static void reorder_block(MPADecodeContext *s, GranuleDef *g)
if (s->sample_rate_index != 8) if (s->sample_rate_index != 8)
ptr = g->sb_hybrid + 36; ptr = g->sb_hybrid + 36;
else else
ptr = g->sb_hybrid + 48; ptr = g->sb_hybrid + 72;
} else { } else {
ptr = g->sb_hybrid; ptr = g->sb_hybrid;
} }
......
...@@ -354,14 +354,7 @@ static int truemotion1_decode_header(TrueMotion1Context *s) ...@@ -354,14 +354,7 @@ static int truemotion1_decode_header(TrueMotion1Context *s)
if (s->flags & FLAG_SPRITE) { if (s->flags & FLAG_SPRITE) {
av_log_ask_for_sample(s->avctx, "SPRITE frame found.\n"); av_log_ask_for_sample(s->avctx, "SPRITE frame found.\n");
/* FIXME header.width, height, xoffset and yoffset aren't initialized */ /* FIXME header.width, height, xoffset and yoffset aren't initialized */
#if 0
s->w = header.width;
s->h = header.height;
s->x = header.xoffset;
s->y = header.yoffset;
#else
return -1; return -1;
#endif
} else { } else {
s->w = header.xsize; s->w = header.xsize;
s->h = header.ysize; s->h = header.ysize;
......
...@@ -1212,7 +1212,8 @@ int attribute_align_arg avcodec_encode_audio(AVCodecContext *avctx, ...@@ -1212,7 +1212,8 @@ int attribute_align_arg avcodec_encode_audio(AVCodecContext *avctx,
avctx->sample_fmt, 1); avctx->sample_fmt, 1);
if ((ret = avcodec_fill_audio_frame(frame, avctx->channels, if ((ret = avcodec_fill_audio_frame(frame, avctx->channels,
avctx->sample_fmt, avctx->sample_fmt,
(const uint8_t *)samples, samples_size, 1))) (const uint8_t *) samples,
samples_size, 1)))
return ret; return ret;
/* fabricate frame pts from sample count. /* fabricate frame pts from sample count.
......
...@@ -220,7 +220,7 @@ static int roq_read_packet(AVFormatContext *s, ...@@ -220,7 +220,7 @@ static int roq_read_packet(AVFormatContext *s,
} }
AVInputFormat ff_roq_demuxer = { AVInputFormat ff_roq_demuxer = {
.name = "RoQ", .name = "roq",
.long_name = NULL_IF_CONFIG_SMALL("id RoQ format"), .long_name = NULL_IF_CONFIG_SMALL("id RoQ format"),
.priv_data_size = sizeof(RoqDemuxContext), .priv_data_size = sizeof(RoqDemuxContext),
.read_probe = roq_probe, .read_probe = roq_probe,
......
...@@ -36,7 +36,7 @@ static int roq_write_header(struct AVFormatContext *s) ...@@ -36,7 +36,7 @@ static int roq_write_header(struct AVFormatContext *s)
} }
AVOutputFormat ff_roq_muxer = { AVOutputFormat ff_roq_muxer = {
.name = "RoQ", .name = "roq",
.long_name = NULL_IF_CONFIG_SMALL("raw id RoQ format"), .long_name = NULL_IF_CONFIG_SMALL("raw id RoQ format"),
.extensions = "roq", .extensions = "roq",
.audio_codec = CODEC_ID_ROQ_DPCM, .audio_codec = CODEC_ID_ROQ_DPCM,
......
...@@ -384,7 +384,7 @@ static int iff_read_packet(AVFormatContext *s, ...@@ -384,7 +384,7 @@ static int iff_read_packet(AVFormatContext *s,
} }
AVInputFormat ff_iff_demuxer = { AVInputFormat ff_iff_demuxer = {
.name = "IFF", .name = "iff",
.long_name = NULL_IF_CONFIG_SMALL("Interchange File Format"), .long_name = NULL_IF_CONFIG_SMALL("Interchange File Format"),
.priv_data_size = sizeof(IffDemuxContext), .priv_data_size = sizeof(IffDemuxContext),
.read_probe = iff_probe, .read_probe = iff_probe,
......
...@@ -128,7 +128,7 @@ static int iss_read_packet(AVFormatContext *s, AVPacket *pkt) ...@@ -128,7 +128,7 @@ static int iss_read_packet(AVFormatContext *s, AVPacket *pkt)
} }
AVInputFormat ff_iss_demuxer = { AVInputFormat ff_iss_demuxer = {
.name = "ISS", .name = "iss",
.long_name = NULL_IF_CONFIG_SMALL("Funcom ISS format"), .long_name = NULL_IF_CONFIG_SMALL("Funcom ISS format"),
.priv_data_size = sizeof(IssDemuxContext), .priv_data_size = sizeof(IssDemuxContext),
.read_probe = iss_probe, .read_probe = iss_probe,
......
...@@ -194,7 +194,7 @@ static int mtv_read_packet(AVFormatContext *s, AVPacket *pkt) ...@@ -194,7 +194,7 @@ static int mtv_read_packet(AVFormatContext *s, AVPacket *pkt)
} }
AVInputFormat ff_mtv_demuxer = { AVInputFormat ff_mtv_demuxer = {
.name = "MTV", .name = "mtv",
.long_name = NULL_IF_CONFIG_SMALL("MTV format"), .long_name = NULL_IF_CONFIG_SMALL("MTV format"),
.priv_data_size = sizeof(MTVDemuxContext), .priv_data_size = sizeof(MTVDemuxContext),
.read_probe = mtv_probe, .read_probe = mtv_probe,
......
...@@ -228,7 +228,7 @@ AVOutputFormat *av_guess_format(const char *short_name, const char *filename, ...@@ -228,7 +228,7 @@ AVOutputFormat *av_guess_format(const char *short_name, const char *filename,
score_max = 0; score_max = 0;
while ((fmt = av_oformat_next(fmt))) { while ((fmt = av_oformat_next(fmt))) {
score = 0; score = 0;
if (fmt->name && short_name && !strcmp(fmt->name, short_name)) if (fmt->name && short_name && !av_strcasecmp(fmt->name, short_name))
score += 100; score += 100;
if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type)) if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type))
score += 10; score += 10;
......
...@@ -86,16 +86,16 @@ FATE_LAVF = $(LAVF_TESTS:%=fate-lavf-%) ...@@ -86,16 +86,16 @@ FATE_LAVF = $(LAVF_TESTS:%=fate-lavf-%)
FATE_LAVFI = $(LAVFI_TESTS:%=fate-lavfi-%) FATE_LAVFI = $(LAVFI_TESTS:%=fate-lavfi-%)
FATE_SEEK = $(SEEK_TESTS:seek_%=fate-seek-%) FATE_SEEK = $(SEEK_TESTS:seek_%=fate-seek-%)
FATE = $(FATE_ACODEC) \ FATE_AVCONV += $(FATE_ACODEC) \
$(FATE_VCODEC) \ $(FATE_VCODEC) \
$(FATE_LAVF) \ $(FATE_LAVF) \
$(FATE_SEEK) \ $(FATE_LAVFI) \
$(FATE_SEEK) \
FATE_FFMPEG += $(FATE_FFMPEG-yes) $(FATE_AVCONV) $(FATE_AVCONV-yes) FATE_FFMPEG += $(FATE_FFMPEG-yes) $(FATE_AVCONV) $(FATE_AVCONV-yes)
FATE-$(CONFIG_FFMPEG) += $(FATE_FFMPEG) FATE-$(CONFIG_FFMPEG) += $(FATE_FFMPEG)
FATE-$(CONFIG_AVCODEC) += $(FATE_LIBAVCODEC) FATE-$(CONFIG_AVCODEC) += $(FATE_LIBAVCODEC)
FATE-$(CONFIG_AVFILTER) += $(FATE_LAVFI)
FATE_SAMPLES-$(CONFIG_FFMPEG) += $(FATE_SAMPLES_AVCONV) $(FATE_SAMPLES_FFMPEG) FATE_SAMPLES-$(CONFIG_FFMPEG) += $(FATE_SAMPLES_AVCONV) $(FATE_SAMPLES_FFMPEG)
FATE_SAMPLES += $(FATE_SAMPLES-yes) FATE_SAMPLES += $(FATE_SAMPLES-yes)
......
...@@ -119,7 +119,7 @@ FATE_VIDEO += fate-id-cin-video ...@@ -119,7 +119,7 @@ FATE_VIDEO += fate-id-cin-video
fate-id-cin-video: CMD = framecrc -i $(SAMPLES)/idcin/idlog-2MB.cin -pix_fmt rgb24 fate-id-cin-video: CMD = framecrc -i $(SAMPLES)/idcin/idlog-2MB.cin -pix_fmt rgb24
FATE_VIDEO-$(CONFIG_AVFILTER) += 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 += fate-iff-byterun1
fate-iff-byterun1: CMD = framecrc -i $(SAMPLES)/iff/ASH.LBM -pix_fmt rgb24 fate-iff-byterun1: CMD = framecrc -i $(SAMPLES)/iff/ASH.LBM -pix_fmt rgb24
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment