diff options
| author | Tim Redfern <tim@eclectronics.org> | 2013-12-29 12:19:38 +0000 |
|---|---|---|
| committer | Tim Redfern <tim@eclectronics.org> | 2013-12-29 12:19:38 +0000 |
| commit | f7813a5324be39d13ab536c245d15dfc602a7849 (patch) | |
| tree | fad99148b88823d34a5df2f0a25881a002eb291b /ffmpeg/libavcodec/ivi_common.c | |
| parent | b7a5a477b8ff4d4e3028b9dfb9a9df0a41463f92 (diff) | |
basic type mechanism working
Diffstat (limited to 'ffmpeg/libavcodec/ivi_common.c')
| -rw-r--r-- | ffmpeg/libavcodec/ivi_common.c | 594 |
1 files changed, 360 insertions, 234 deletions
diff --git a/ffmpeg/libavcodec/ivi_common.c b/ffmpeg/libavcodec/ivi_common.c index 265c645..a4d2434 100644 --- a/ffmpeg/libavcodec/ivi_common.c +++ b/ffmpeg/libavcodec/ivi_common.c @@ -35,12 +35,59 @@ #include "ivi_common.h" #include "ivi_dsp.h" -extern const IVIHuffDesc ff_ivi_mb_huff_desc[8]; ///< static macroblock huffman tables -extern const IVIHuffDesc ff_ivi_blk_huff_desc[8]; ///< static block huffman tables +/** + * These are 2x8 predefined Huffman codebooks for coding macroblock/block + * signals. They are specified using "huffman descriptors" in order to + * avoid huge static tables. The decoding tables will be generated at + * startup from these descriptors. + */ +/** static macroblock huffman tables */ +static const IVIHuffDesc ivi_mb_huff_desc[8] = { + {8, {0, 4, 5, 4, 4, 4, 6, 6}}, + {12, {0, 2, 2, 3, 3, 3, 3, 5, 3, 2, 2, 2}}, + {12, {0, 2, 3, 4, 3, 3, 3, 3, 4, 3, 2, 2}}, + {12, {0, 3, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2}}, + {13, {0, 4, 4, 3, 3, 3, 3, 2, 3, 3, 2, 1, 1}}, + {9, {0, 4, 4, 4, 4, 3, 3, 3, 2}}, + {10, {0, 4, 4, 4, 4, 3, 3, 2, 2, 2}}, + {12, {0, 4, 4, 4, 3, 3, 2, 3, 2, 2, 2, 2}} +}; + +/** static block huffman tables */ +static const IVIHuffDesc ivi_blk_huff_desc[8] = { + {10, {1, 2, 3, 4, 4, 7, 5, 5, 4, 1}}, + {11, {2, 3, 4, 4, 4, 7, 5, 4, 3, 3, 2}}, + {12, {2, 4, 5, 5, 5, 5, 6, 4, 4, 3, 1, 1}}, + {13, {3, 3, 4, 4, 5, 6, 6, 4, 4, 3, 2, 1, 1}}, + {11, {3, 4, 4, 5, 5, 5, 6, 5, 4, 2, 2}}, + {13, {3, 4, 5, 5, 5, 5, 6, 4, 3, 3, 2, 1, 1}}, + {13, {3, 4, 5, 5, 5, 6, 5, 4, 3, 3, 2, 1, 1}}, + {9, {3, 4, 4, 5, 5, 5, 6, 5, 5}} +}; static VLC ivi_mb_vlc_tabs [8]; ///< static macroblock Huffman tables static VLC ivi_blk_vlc_tabs[8]; ///< static block Huffman tables +typedef void (*ivi_mc_func) (int16_t *buf, const int16_t *ref_buf, + uint32_t pitch, int mc_type); + +static int ivi_mc(IVIBandDesc *band, ivi_mc_func mc, + int offs, int mv_x, int mv_y, int mc_type) +{ + int ref_offs = offs + mv_y * band->pitch + mv_x; + int buf_size = band->pitch * band->aheight; + int min_size = band->pitch * (band->blk_size - 1) + band->blk_size; + int ref_size = (mc_type > 1) * band->pitch + (mc_type & 1); + + av_assert0(offs >= 0 && ref_offs >= 0 && band->ref_buf); + av_assert0(buf_size - min_size >= offs); + av_assert0(buf_size - min_size - ref_size >= ref_offs); + + mc(band->buf + offs, band->ref_buf + ref_offs, band->pitch, mc_type); + + return 0; +} + /** * Reverse "nbits" bits of the value "val" and return the result * in the least significant bits. @@ -50,9 +97,10 @@ static uint16_t inv_bits(uint16_t val, int nbits) uint16_t res; if (nbits <= 8) { - res = ff_reverse[val] >> (8-nbits); + res = ff_reverse[val] >> (8 - nbits); } else - res = ((ff_reverse[val & 0xFF] << 8) + (ff_reverse[val >> 8])) >> (16-nbits); + res = ((ff_reverse[val & 0xFF] << 8) + + (ff_reverse[val >> 8])) >> (16 - nbits); return res; } @@ -85,7 +133,7 @@ static int ivi_create_huff_from_desc(const IVIHuffDesc *cb, VLC *vlc, int flag) bits[pos] = i + cb->xbits[i] + not_last_row; if (bits[pos] > IVI_VLC_BITS) - return -1; /* invalid descriptor */ + return AVERROR_INVALIDDATA; /* invalid descriptor */ codewords[pos] = inv_bits((prefix | j), bits[pos]); if (!bits[pos]) @@ -100,7 +148,7 @@ static int ivi_create_huff_from_desc(const IVIHuffDesc *cb, VLC *vlc, int flag) (flag ? INIT_VLC_USE_NEW_STATIC : 0) | INIT_VLC_LE); } -void ff_ivi_init_static_vlc(void) +av_cold void ff_ivi_init_static_vlc(void) { int i; static VLC_TYPE table_data[8192 * 16][2]; @@ -111,10 +159,12 @@ void ff_ivi_init_static_vlc(void) for (i = 0; i < 8; i++) { ivi_mb_vlc_tabs[i].table = table_data + i * 2 * 8192; ivi_mb_vlc_tabs[i].table_allocated = 8192; - ivi_create_huff_from_desc(&ff_ivi_mb_huff_desc[i], &ivi_mb_vlc_tabs[i], 1); + ivi_create_huff_from_desc(&ivi_mb_huff_desc[i], + &ivi_mb_vlc_tabs[i], 1); ivi_blk_vlc_tabs[i].table = table_data + (i * 2 + 1) * 8192; ivi_blk_vlc_tabs[i].table_allocated = 8192; - ivi_create_huff_from_desc(&ff_ivi_blk_huff_desc[i], &ivi_blk_vlc_tabs[i], 1); + ivi_create_huff_from_desc(&ivi_blk_huff_desc[i], + &ivi_blk_vlc_tabs[i], 1); } initialized_vlcs = 1; } @@ -138,56 +188,59 @@ static void ivi_huff_desc_copy(IVIHuffDesc *dst, const IVIHuffDesc *src) * @param[in] desc2 ptr to the 2nd descriptor to compare * @return comparison result: 0 - equal, 1 - not equal */ -static int ivi_huff_desc_cmp(const IVIHuffDesc *desc1, const IVIHuffDesc *desc2) +static int ivi_huff_desc_cmp(const IVIHuffDesc *desc1, + const IVIHuffDesc *desc2) { - return desc1->num_rows != desc2->num_rows - || memcmp(desc1->xbits, desc2->xbits, desc1->num_rows); + return desc1->num_rows != desc2->num_rows || + memcmp(desc1->xbits, desc2->xbits, desc1->num_rows); } int ff_ivi_dec_huff_desc(GetBitContext *gb, int desc_coded, int which_tab, IVIHuffTab *huff_tab, AVCodecContext *avctx) { - int i, result; + int i, result; IVIHuffDesc new_huff; if (!desc_coded) { /* select default table */ huff_tab->tab = (which_tab) ? &ivi_blk_vlc_tabs[7] - : &ivi_mb_vlc_tabs [7]; - } else { - huff_tab->tab_sel = get_bits(gb, 3); - if (huff_tab->tab_sel == 7) { - /* custom huffman table (explicitly encoded) */ - 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++) - new_huff.xbits[i] = get_bits(gb, 4); + : &ivi_mb_vlc_tabs [7]; + return 0; + } - /* Have we got the same custom table? Rebuild if not. */ - if (ivi_huff_desc_cmp(&new_huff, &huff_tab->cust_desc) || !huff_tab->cust_tab.table) { - ivi_huff_desc_copy(&huff_tab->cust_desc, &new_huff); + huff_tab->tab_sel = get_bits(gb, 3); + if (huff_tab->tab_sel == 7) { + /* custom huffman table (explicitly encoded) */ + 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; + } - if (huff_tab->cust_tab.table) - ff_free_vlc(&huff_tab->cust_tab); - result = ivi_create_huff_from_desc(&huff_tab->cust_desc, - &huff_tab->cust_tab, 0); - if (result) { - huff_tab->cust_desc.num_rows = 0; // reset faulty description - av_log(avctx, AV_LOG_ERROR, - "Error while initializing custom vlc table!\n"); - return result; - } + for (i = 0; i < new_huff.num_rows; i++) + new_huff.xbits[i] = get_bits(gb, 4); + + /* Have we got the same custom table? Rebuild if not. */ + if (ivi_huff_desc_cmp(&new_huff, &huff_tab->cust_desc) || !huff_tab->cust_tab.table) { + ivi_huff_desc_copy(&huff_tab->cust_desc, &new_huff); + + if (huff_tab->cust_tab.table) + ff_free_vlc(&huff_tab->cust_tab); + result = ivi_create_huff_from_desc(&huff_tab->cust_desc, + &huff_tab->cust_tab, 0); + if (result) { + // reset faulty description + huff_tab->cust_desc.num_rows = 0; + av_log(avctx, AV_LOG_ERROR, + "Error while initializing custom vlc table!\n"); + return result; } - huff_tab->tab = &huff_tab->cust_tab; - } else { - /* select one of predefined tables */ - huff_tab->tab = (which_tab) ? &ivi_blk_vlc_tabs[huff_tab->tab_sel] - : &ivi_mb_vlc_tabs [huff_tab->tab_sel]; } + huff_tab->tab = &huff_tab->cust_tab; + } else { + /* select one of predefined tables */ + huff_tab->tab = (which_tab) ? &ivi_blk_vlc_tabs[huff_tab->tab_sel] + : &ivi_mb_vlc_tabs [huff_tab->tab_sel]; } return 0; @@ -216,17 +269,23 @@ static av_cold void ivi_free_buffers(IVIPlaneDesc *planes) av_freep(&planes[p].bands[b].tiles); } av_freep(&planes[p].bands); + planes[p].num_bands = 0; } } av_cold int ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg) { - int p, b; - uint32_t b_width, b_height, align_fac, width_aligned, height_aligned, buf_size; + int p, b; + uint32_t b_width, b_height, align_fac, width_aligned, + height_aligned, buf_size; IVIBandDesc *band; ivi_free_buffers(planes); + if (cfg->pic_width < 1 || cfg->pic_height < 1 || + cfg->luma_bands < 1 || cfg->chroma_bands < 1) + return AVERROR_INVALIDDATA; + /* fill in the descriptor of the luminance plane */ planes[0].width = cfg->pic_width; planes[0].height = cfg->pic_height; @@ -245,8 +304,10 @@ av_cold int ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg) /* select band dimensions: if there is only one band then it * has the full size, if there are several bands each of them * has only half size */ - b_width = planes[p].num_bands == 1 ? planes[p].width : (planes[p].width + 1) >> 1; - b_height = planes[p].num_bands == 1 ? planes[p].height : (planes[p].height + 1) >> 1; + b_width = planes[p].num_bands == 1 ? planes[p].width + : (planes[p].width + 1) >> 1; + b_height = planes[p].num_bands == 1 ? planes[p].height + : (planes[p].height + 1) >> 1; /* luma band buffers will be aligned on 16x16 (max macroblock size) */ /* chroma band buffers will be aligned on 8x8 (max macroblock size) */ @@ -275,19 +336,58 @@ av_cold int ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg) if (!band->bufs[2]) return AVERROR(ENOMEM); } + /* reset custom vlc */ + planes[p].bands[0].blk_vlc.cust_desc.num_rows = 0; + } + } + + return 0; +} + +static int ivi_init_tiles(IVIBandDesc *band, IVITile *ref_tile, + int p, int b, int t_height, int t_width) +{ + int x, y; + IVITile *tile = band->tiles; + + for (y = 0; y < band->height; y += t_height) { + for (x = 0; x < band->width; x += t_width) { + tile->xpos = x; + tile->ypos = y; + tile->mb_size = band->mb_size; + tile->width = FFMIN(band->width - x, t_width); + tile->height = FFMIN(band->height - y, t_height); + tile->is_empty = tile->data_size = 0; + /* calculate number of macroblocks */ + tile->num_MBs = IVI_MBs_PER_TILE(tile->width, tile->height, + band->mb_size); + + av_freep(&tile->mbs); + tile->mbs = av_mallocz(tile->num_MBs * sizeof(IVIMbInfo)); + if (!tile->mbs) + return AVERROR(ENOMEM); - planes[p].bands[0].blk_vlc.cust_desc.num_rows = 0; /* reset custom vlc */ + tile->ref_mbs = 0; + if (p || b) { + if (tile->num_MBs != ref_tile->num_MBs) { + av_log(NULL, AV_LOG_DEBUG, "ref_tile mismatch\n"); + return AVERROR_INVALIDDATA; + } + tile->ref_mbs = ref_tile->mbs; + ref_tile++; + } + tile++; } } return 0; } -av_cold int ff_ivi_init_tiles(IVIPlaneDesc *planes, int tile_width, int tile_height) +av_cold int ff_ivi_init_tiles(IVIPlaneDesc *planes, + int tile_width, int tile_height) { - int p, b, x, y, x_tiles, y_tiles, t_width, t_height; + int p, b, x_tiles, y_tiles, t_width, t_height, ret; IVIBandDesc *band; - IVITile *tile, *ref_tile; for (p = 0; p < 3; p++) { t_width = !p ? tile_width : (tile_width + 3) >> 2; @@ -311,44 +411,14 @@ av_cold int ff_ivi_init_tiles(IVIPlaneDesc *planes, int tile_width, int tile_hei if (!band->tiles) return AVERROR(ENOMEM); - tile = band->tiles; - /* use the first luma band as reference for motion vectors * and quant */ - ref_tile = planes[0].bands[0].tiles; - - for (y = 0; y < band->height; y += t_height) { - for (x = 0; x < band->width; x += t_width) { - tile->xpos = x; - tile->ypos = y; - tile->mb_size = band->mb_size; - tile->width = FFMIN(band->width - x, t_width); - tile->height = FFMIN(band->height - y, t_height); - tile->is_empty = tile->data_size = 0; - /* calculate number of macroblocks */ - tile->num_MBs = IVI_MBs_PER_TILE(tile->width, tile->height, - band->mb_size); - - av_freep(&tile->mbs); - tile->mbs = av_malloc(tile->num_MBs * sizeof(IVIMbInfo)); - if (!tile->mbs) - return AVERROR(ENOMEM); - - tile->ref_mbs = 0; - if (p || b) { - if (tile->num_MBs <= ref_tile->num_MBs) { - tile->ref_mbs = ref_tile->mbs; - }else - av_log(NULL, AV_LOG_DEBUG, "Cannot use ref_tile, too few mbs\n"); - ref_tile++; - } - - tile++; - } - } - - }// for b - }// for p + ret = ivi_init_tiles(band, planes[0].bands[0].tiles, + p, b, t_height, t_width); + if (ret < 0) + return ret; + } + } return 0; } @@ -380,6 +450,117 @@ static int ivi_dec_tile_data_size(GetBitContext *gb) return len; } +static int ivi_dc_transform(IVIBandDesc *band, int *prev_dc, int buf_offs, + int blk_size) +{ + int buf_size = band->pitch * band->aheight - buf_offs; + int min_size = (blk_size - 1) * band->pitch + blk_size; + + if (min_size > buf_size) + return AVERROR_INVALIDDATA; + + band->dc_transform(prev_dc, band->buf + buf_offs, + band->pitch, blk_size); + + return 0; +} + +static int ivi_decode_coded_blocks(GetBitContext *gb, IVIBandDesc *band, + ivi_mc_func mc, int mv_x, int mv_y, + int *prev_dc, int is_intra, int mc_type, + uint32_t quant, int offs, + AVCodecContext *avctx) +{ + const uint16_t *base_tab = is_intra ? band->intra_base : band->inter_base; + RVMapDesc *rvmap = band->rv_map; + uint8_t col_flags[8]; + int32_t trvec[64]; + uint32_t sym = 0, lo, hi, q; + int pos, run, val; + int blk_size = band->blk_size; + int num_coeffs = blk_size * blk_size; + int col_mask = blk_size - 1; + int scan_pos = -1; + int min_size = band->pitch * (band->transform_size - 1) + + band->transform_size; + int buf_size = band->pitch * band->aheight - offs; + + if (min_size > buf_size) + return AVERROR_INVALIDDATA; + + if (!band->scan) { + av_log(avctx, AV_LOG_ERROR, "Scan pattern is not set.\n"); + return AVERROR_INVALIDDATA; + } + + /* zero transform vector */ + memset(trvec, 0, num_coeffs * sizeof(trvec[0])); + /* zero column flags */ + memset(col_flags, 0, sizeof(col_flags)); + while (scan_pos <= num_coeffs) { + sym = get_vlc2(gb, band->blk_vlc.tab->table, + IVI_VLC_BITS, 1); + if (sym == rvmap->eob_sym) + break; /* End of block */ + + /* Escape - run/val explicitly coded using 3 vlc codes */ + if (sym == rvmap->esc_sym) { + run = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1) + 1; + lo = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1); + hi = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1); + /* merge them and convert into signed val */ + val = IVI_TOSIGNED((hi << 6) | lo); + } else { + if (sym >= 256U) { + av_log(avctx, AV_LOG_ERROR, "Invalid sym encountered: %d.\n", sym); + return AVERROR_INVALIDDATA; + } + run = rvmap->runtab[sym]; + val = rvmap->valtab[sym]; + } + + /* de-zigzag and dequantize */ + scan_pos += run; + if (scan_pos >= num_coeffs || scan_pos < 0) + break; + pos = band->scan[scan_pos]; + + if (!val) + av_dlog(avctx, "Val = 0 encountered!\n"); + + q = (base_tab[pos] * quant) >> 9; + if (q > 1) + val = val * q + FFSIGN(val) * (((q ^ 1) - 1) >> 1); + trvec[pos] = val; + /* track columns containing non-zero coeffs */ + col_flags[pos & col_mask] |= !!val; + } + + if (scan_pos < 0 || scan_pos >= num_coeffs && sym != rvmap->eob_sym) + return AVERROR_INVALIDDATA; /* corrupt block data */ + + /* undoing DC coeff prediction for intra-blocks */ + if (is_intra && band->is_2d_trans) { + *prev_dc += trvec[0]; + trvec[0] = *prev_dc; + col_flags[0] |= !!*prev_dc; + } + + if(band->transform_size > band->blk_size){ + av_log(NULL, AV_LOG_ERROR, "Too large transform\n"); + return AVERROR_INVALIDDATA; + } + + /* apply inverse transform */ + band->inv_transform(trvec, band->buf + offs, + band->pitch, col_flags); + + /* apply motion compensation */ + if (!is_intra) + return ivi_mc(band, mc, offs, mv_x, mv_y, mc_type); + + return 0; +} /* * Decode block data: * extract huffman-coded transform coefficients from the bitstream, @@ -391,27 +572,22 @@ static int ivi_dec_tile_data_size(GetBitContext *gb) * @param[in] tile pointer to the tile descriptor * @return result code: 0 - OK, -1 = error (corrupted blocks data) */ -static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile, - AVCodecContext *avctx) +static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, + IVITile *tile, AVCodecContext *avctx) { - int mbn, blk, num_blocks, num_coeffs, blk_size, scan_pos, run, val, - pos, is_intra, mc_type = 0, av_uninit(mv_x), av_uninit(mv_y), col_mask; - uint8_t col_flags[8]; - int32_t prev_dc, trvec[64]; - uint32_t cbp, av_uninit(sym), lo, hi, quant, buf_offs, q; - IVIMbInfo *mb; - RVMapDesc *rvmap = band->rv_map; - void (*mc_with_delta_func)(int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type); - void (*mc_no_delta_func) (int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type); - const uint16_t *base_tab; - const uint8_t *scale_tab; - - prev_dc = 0; /* init intra prediction for the DC coefficient */ - + int mbn, blk, num_blocks, blk_size, ret, is_intra, mc_type = 0; + int mv_x = 0, mv_y = 0; + int32_t prev_dc; + uint32_t cbp, quant, buf_offs; + IVIMbInfo *mb; + ivi_mc_func mc_with_delta_func, mc_no_delta_func; + const uint8_t *scale_tab; + + /* init intra prediction for the DC coefficient */ + prev_dc = 0; blk_size = band->blk_size; - col_mask = blk_size - 1; /* column mask for tracking non-zero coeffs */ - num_blocks = (band->mb_size != blk_size) ? 4 : 1; /* number of blocks per mb */ - num_coeffs = blk_size * blk_size; + /* number of blocks per mb */ + num_blocks = (band->mb_size != blk_size) ? 4 : 1; if (blk_size == 8) { mc_with_delta_func = ff_ivi_mc_8x8_delta; mc_no_delta_func = ff_ivi_mc_8x8_no_delta; @@ -425,9 +601,12 @@ static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile cbp = mb->cbp; buf_offs = mb->buf_offs; - quant = av_clip(band->glob_quant + mb->q_delta, 0, 23); + quant = band->glob_quant + mb->q_delta; + if (avctx->codec_id == AV_CODEC_ID_INDEO4) + quant = av_clip(quant, 0, 31); + else + quant = av_clip(quant, 0, 23); - base_tab = is_intra ? band->intra_base : band->inter_base; scale_tab = is_intra ? band->intra_scale : band->inter_scale; if (scale_tab) quant = scale_tab[quant]; @@ -448,10 +627,10 @@ static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile 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) { + 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; } } @@ -467,83 +646,25 @@ static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile } if (cbp & 1) { /* block coded ? */ - if (!band->scan) { - av_log(avctx, AV_LOG_ERROR, "Scan pattern is not set.\n"); - return AVERROR_INVALIDDATA; - } - - scan_pos = -1; - memset(trvec, 0, num_coeffs*sizeof(trvec[0])); /* zero transform vector */ - memset(col_flags, 0, sizeof(col_flags)); /* zero column flags */ - - while (scan_pos <= num_coeffs) { - sym = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1); - if (sym == rvmap->eob_sym) - break; /* End of block */ - - if (sym == rvmap->esc_sym) { /* Escape - run/val explicitly coded using 3 vlc codes */ - run = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1) + 1; - lo = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1); - hi = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1); - val = IVI_TOSIGNED((hi << 6) | lo); /* merge them and convert into signed val */ - } else { - if (sym >= 256U) { - av_log(avctx, AV_LOG_ERROR, "Invalid sym encountered: %d.\n", sym); - return -1; - } - run = rvmap->runtab[sym]; - val = rvmap->valtab[sym]; - } - - /* de-zigzag and dequantize */ - scan_pos += run; - if (scan_pos >= (unsigned)num_coeffs) - break; - pos = band->scan[scan_pos]; - - if (!val) - av_dlog(avctx, "Val = 0 encountered!\n"); - - q = (base_tab[pos] * quant) >> 9; - if (q > 1) - val = val * q + FFSIGN(val) * (((q ^ 1) - 1) >> 1); - trvec[pos] = val; - col_flags[pos & col_mask] |= !!val; /* track columns containing non-zero coeffs */ - }// while - - if (scan_pos >= num_coeffs && sym != rvmap->eob_sym) - return -1; /* corrupt block data */ - - /* undoing DC coeff prediction for intra-blocks */ - if (is_intra && band->is_2d_trans) { - prev_dc += trvec[0]; - trvec[0] = prev_dc; - col_flags[0] |= !!prev_dc; - } - if(band->transform_size > band->blk_size){ - av_log(NULL, AV_LOG_ERROR, "Too large transform\n"); - return AVERROR_INVALIDDATA; - } - /* apply inverse transform */ - band->inv_transform(trvec, band->buf + buf_offs, - band->pitch, col_flags); - - /* apply motion compensation */ - if (!is_intra) - mc_with_delta_func(band->buf + buf_offs, - band->ref_buf + buf_offs + mv_y * band->pitch + mv_x, - band->pitch, mc_type); + ret = ivi_decode_coded_blocks(gb, band, mc_with_delta_func, + mv_x, mv_y, &prev_dc, is_intra, + mc_type, quant, buf_offs, avctx); + if (ret < 0) + return ret; } else { /* block not coded */ /* for intra blocks apply the dc slant transform */ /* for inter - perform the motion compensation without delta */ if (is_intra) { - band->dc_transform(&prev_dc, band->buf + buf_offs, - band->pitch, blk_size); - } else - mc_no_delta_func(band->buf + buf_offs, - band->ref_buf + buf_offs + mv_y * band->pitch + mv_x, - band->pitch, mc_type); + ret = ivi_dc_transform(band, &prev_dc, buf_offs, blk_size); + if (ret < 0) + return ret; + } else { + ret = ivi_mc(band, mc_no_delta_func, buf_offs, + mv_x, mv_y, mc_type); + if (ret < 0) + return ret; + } } cbp >>= 1; @@ -568,12 +689,11 @@ static int ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, IVITile *tile, int32_t mv_scale) { int x, y, need_mc, mbn, blk, num_blocks, mv_x, mv_y, mc_type; - int offs, mb_offset, row_offset; + int offs, mb_offset, row_offset, ret; IVIMbInfo *mb, *ref_mb; const int16_t *src; int16_t *dst; - void (*mc_no_delta_func)(int16_t *buf, const int16_t *ref_buf, uint32_t pitch, - int mc_type); + ivi_mc_func mc_no_delta_func; if (tile->num_MBs != IVI_MBs_PER_TILE(tile->width, tile->height, band->mb_size)) { av_log(avctx, AV_LOG_ERROR, "Allocated tile size %d mismatches " @@ -663,9 +783,10 @@ static int ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, for (blk = 0; blk < num_blocks; blk++) { /* adjust block position in the buffer according with its number */ offs = mb->buf_offs + band->blk_size * ((blk & 1) + !!(blk & 2) * band->pitch); - mc_no_delta_func(band->buf + offs, - band->ref_buf + offs + mv_y * band->pitch + mv_x, - band->pitch, mc_type); + ret = ivi_mc(band, mc_no_delta_func, offs, + mv_x, mv_y, mc_type); + if (ret < 0) + return ret; } } } else { @@ -804,8 +925,16 @@ static int decode_band(IVI45DecContext *ctx, break; result = ivi_decode_blocks(&ctx->gb, band, tile, avctx); - if (result < 0 || ((get_bits_count(&ctx->gb) - pos) >> 3) != tile->data_size) { - av_log(avctx, AV_LOG_ERROR, "Corrupted tile data encountered!\n"); + if (result < 0) { + av_log(avctx, AV_LOG_ERROR, + "Corrupted tile data encountered!\n"); + break; + } + + if (((get_bits_count(&ctx->gb) - pos) >> 3) != tile->data_size) { + av_log(avctx, AV_LOG_ERROR, + "Tile data_size mismatch!\n"); + result = AVERROR_INVALIDDATA; break; } @@ -813,7 +942,8 @@ static int decode_band(IVI45DecContext *ctx, } } - /* restore the selected rvmap table by applying its corrections in reverse order */ + /* 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]; @@ -830,7 +960,8 @@ static int decode_band(IVI45DecContext *ctx, 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 checksum mismatch! Plane %d, band %d, " + "received: %x, calculated: %x\n", band->plane, band->band_num, band->checksum, chksum); } } @@ -858,14 +989,19 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (result) { av_log(avctx, AV_LOG_ERROR, "Error while decoding picture header: %d\n", result); - return -1; + return result; } if (ctx->gop_invalid) return AVERROR_INVALIDDATA; if (ctx->gop_flags & IVI5_IS_PROTECTED) { - av_log(avctx, AV_LOG_ERROR, "Password-protected clip!\n"); - return -1; + avpriv_report_missing_feature(avctx, "Password-protected clip!\n"); + return AVERROR_PATCHWELCOME; + } + + if (!ctx->planes[0].bands) { + av_log(avctx, AV_LOG_ERROR, "Color planes not initialized yet\n"); + return AVERROR_INVALIDDATA; } ctx->switch_buffers(ctx); @@ -877,25 +1013,41 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, for (p = 0; p < 3; p++) { for (b = 0; b < ctx->planes[p].num_bands; b++) { result = decode_band(ctx, &ctx->planes[p].bands[b], avctx); - if (result) { + if (result < 0) { av_log(avctx, AV_LOG_ERROR, "Error while decoding band: %d, plane: %d\n", b, p); - return -1; + return result; } } } ctx->buf_invalid[ctx->dst_buf] = 0; + } else { + if (ctx->is_scalable) + return AVERROR_INVALIDDATA; + + for (p = 0; p < 3; p++) { + if (!ctx->planes[p].bands[0].buf) + return AVERROR_INVALIDDATA; + } } 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 == AV_CODEC_ID_INDEO4 && ctx->frame_type == 0/*FRAMETYPE_INTRA*/) { - while (get_bits(&ctx->gb, 8)); // skip version string + /* 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 == AV_CODEC_ID_INDEO4 && + ctx->frame_type == 0/*FRAMETYPE_INTRA*/) { + // skip version string + while (get_bits(&ctx->gb, 8)) { + if (get_bits_left(&ctx->gb) < 8) + return AVERROR_INVALIDDATA; + } + 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"); @@ -904,7 +1056,10 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (!ctx->is_nonnull_frame(ctx)) return buf_size; - avcodec_set_dimensions(avctx, ctx->planes[0].width, ctx->planes[0].height); + result = ff_set_dimensions(avctx, ctx->planes[0].width, ctx->planes[0].height); + if (result < 0) + return result; + if ((result = ff_get_buffer(avctx, frame, 0)) < 0) return result; @@ -959,35 +1114,6 @@ av_cold int ff_ivi_decode_close(AVCodecContext *avctx) /** - * These are 2x8 predefined Huffman codebooks for coding macroblock/block - * signals. They are specified using "huffman descriptors" in order to - * avoid huge static tables. The decoding tables will be generated at - * startup from these descriptors. - */ -const IVIHuffDesc ff_ivi_mb_huff_desc[8] = { - {8, {0, 4, 5, 4, 4, 4, 6, 6}}, - {12, {0, 2, 2, 3, 3, 3, 3, 5, 3, 2, 2, 2}}, - {12, {0, 2, 3, 4, 3, 3, 3, 3, 4, 3, 2, 2}}, - {12, {0, 3, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2}}, - {13, {0, 4, 4, 3, 3, 3, 3, 2, 3, 3, 2, 1, 1}}, - {9, {0, 4, 4, 4, 4, 3, 3, 3, 2}}, - {10, {0, 4, 4, 4, 4, 3, 3, 2, 2, 2}}, - {12, {0, 4, 4, 4, 3, 3, 2, 3, 2, 2, 2, 2}} -}; - -const IVIHuffDesc ff_ivi_blk_huff_desc[8] = { - {10, {1, 2, 3, 4, 4, 7, 5, 5, 4, 1}}, - {11, {2, 3, 4, 4, 4, 7, 5, 4, 3, 3, 2}}, - {12, {2, 4, 5, 5, 5, 5, 6, 4, 4, 3, 1, 1}}, - {13, {3, 3, 4, 4, 5, 6, 6, 4, 4, 3, 2, 1, 1}}, - {11, {3, 4, 4, 5, 5, 5, 6, 5, 4, 2, 2}}, - {13, {3, 4, 5, 5, 5, 5, 6, 4, 3, 3, 2, 1, 1}}, - {13, {3, 4, 5, 5, 5, 6, 5, 4, 3, 3, 2, 1, 1}}, - {9, {3, 4, 4, 5, 5, 5, 6, 5, 5}} -}; - - -/** * Scan patterns shared between indeo4 and indeo5 */ const uint8_t ff_ivi_vertical_scan_8x8[64] = { |
