From d8dab6c3b85cdf472e50ac96f70a6f5ec51855ba Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Sun, 30 Jun 2013 10:11:05 +0200 Subject: [PATCH 01/12] indeo: use proper error code (cherry picked from commit dd3754a48854cd570d38db72394491aab0f36570) Signed-off-by: Reinhard Tartler --- libavcodec/ivi_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c index 956bbb162a..842a53d052 100644 --- a/libavcodec/ivi_common.c +++ b/libavcodec/ivi_common.c @@ -837,7 +837,7 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return AVERROR_INVALIDDATA; if (ctx->gop_flags & IVI5_IS_PROTECTED) { - avpriv_report_missing_feature(avctx, "Password-protected clip!\n"); + av_log(avctx, AV_LOG_ERROR, "Password-protected clip!\n"); return AVERROR_PATCHWELCOME; } From 33388299fbb4daa9c58798dc90bea0c8af2e72a7 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Wed, 3 Jul 2013 11:18:30 +0200 Subject: [PATCH 02/12] indeo: use a typedef for the mc function pointer (cherry picked from commit e6d8acf6a8fba4743eb56eabe72a741d1bbee3cb) Signed-off-by: Luca Barbato --- libavcodec/ivi_common.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c index 842a53d052..f0269066f9 100644 --- a/libavcodec/ivi_common.c +++ b/libavcodec/ivi_common.c @@ -41,6 +41,9 @@ extern const IVIHuffDesc ff_ivi_blk_huff_desc[8]; ///< static block huffman tabl 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); + /** * Reverse "nbits" bits of the value "val" and return the result * in the least significant bits. @@ -394,8 +397,7 @@ static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile uint32_t cbp, 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); + ivi_mc_func mc_with_delta_func, mc_no_delta_func; const uint16_t *base_tab; const uint8_t *scale_tab; @@ -563,8 +565,7 @@ static int ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, 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 " From d76480e6ba4022869857b748939053203a770a88 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Wed, 3 Jul 2013 12:58:40 +0200 Subject: [PATCH 03/12] indeo: Refactor ff_ivi_dec_huff_desc Spare an indentation level. (cherry picked from commit f6f36ca8ca1b2526d3abff7d7c627322d3bce912) Signed-off-by: Luca Barbato --- libavcodec/ivi_common.c | 68 +++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c index f0269066f9..77cdce9edd 100644 --- a/libavcodec/ivi_common.c +++ b/libavcodec/ivi_common.c @@ -156,41 +156,43 @@ int ff_ivi_dec_huff_desc(GetBitContext *gb, int desc_coded, int which_tab, 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; - } + : &ivi_mb_vlc_tabs [7]; + return 0; + } - 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)) { - 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) { - 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; - } - } - 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_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); + + /* Have we got the same custom table? Rebuild if not. */ + if (ivi_huff_desc_cmp(&new_huff, &huff_tab->cust_desc)) { + 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]; } return 0; From b9892e181370b070d949b250312cbd7104b06612 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Wed, 3 Jul 2013 13:59:16 +0200 Subject: [PATCH 04/12] indeo: Refactor ff_ivi_init_tiles and ivi_decode_blocks Spin large and mostly self contained blocks into stand alone functions. (cherry picked from commit 62256010e9bc8879e2bf7f3b94af8ff85e239082) Signed-off-by: Luca Barbato --- libavcodec/ivi_common.c | 273 ++++++++++++++++++++++------------------ 1 file changed, 153 insertions(+), 120 deletions(-) diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c index 77cdce9edd..1b71e7417a 100644 --- a/libavcodec/ivi_common.c +++ b/libavcodec/ivi_common.c @@ -286,11 +286,46 @@ av_cold int ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg) return 0; } -av_cold int ff_ivi_init_tiles(IVIPlaneDesc *planes, int tile_width, int tile_height) +static int ivi_init_tiles(IVIBandDesc *band, IVITile *ref_tile, + int p, int b, int t_height, int t_width) { - int p, b, x, y, x_tiles, y_tiles, t_width, t_height; + 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_malloc(tile->num_MBs * sizeof(IVIMbInfo)); + if (!tile->mbs) + return AVERROR(ENOMEM); + + tile->ref_mbs = 0; + if (p || b) { + 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) +{ + 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; @@ -312,41 +347,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) { - tile->ref_mbs = ref_tile->mbs; - 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; } @@ -378,6 +386,94 @@ static int ivi_dec_tile_data_size(GetBitContext *gb) return len; } + +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; + + 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) + 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 >= 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; + } + + /* apply inverse transform */ + band->inv_transform(trvec, band->buf + offs, + band->pitch, col_flags); + + /* apply motion compensation */ + if (!is_intra) + mc(band->buf + offs, + band->ref_buf + offs + mv_y * band->pitch + mv_x, + band->pitch, mc_type); + + return 0; +} /* * Decode block data: * extract huffman-coded transform coefficients from the bitstream, @@ -389,26 +485,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, mv_x, mv_y, col_mask; - uint8_t col_flags[8]; - int32_t prev_dc, trvec[64]; - uint32_t cbp, sym, lo, hi, quant, buf_offs, q; - IVIMbInfo *mb; - RVMapDesc *rvmap = band->rv_map; + 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 uint16_t *base_tab; - const uint8_t *scale_tab; - - prev_dc = 0; /* init intra prediction for the DC coefficient */ + 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; @@ -424,7 +516,6 @@ static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile quant = av_clip(band->glob_quant + mb->q_delta, 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]; @@ -445,10 +536,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; } } @@ -464,69 +555,11 @@ 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 AVERROR_INVALIDDATA; - } - run = rvmap->runtab[sym]; - val = rvmap->valtab[sym]; - } - - /* de-zigzag and dequantize */ - scan_pos += run; - if (scan_pos >= 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 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; - } - - /* 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 */ From 80d73b4adacac449fc528cb564b9fd88efa47f88 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Wed, 3 Jul 2013 14:01:32 +0200 Subject: [PATCH 05/12] indeo: Cosmetic formatting Trim some overly long lines. (cherry picked from commit 6dfacd7ab126aea1392949d1aa10fdc3d3eeb911) Signed-off-by: Luca Barbato --- libavcodec/ivi_common.c | 52 +++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c index 1b71e7417a..0caefe1ed6 100644 --- a/libavcodec/ivi_common.c +++ b/libavcodec/ivi_common.c @@ -53,9 +53,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; } @@ -114,10 +115,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(&ff_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(&ff_ivi_blk_huff_desc[i], + &ivi_blk_vlc_tabs[i], 1); } initialized_vlcs = 1; } @@ -141,16 +144,17 @@ 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) { @@ -225,8 +229,9 @@ static av_cold void ivi_free_buffers(IVIPlaneDesc *planes) 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); @@ -249,8 +254,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) */ @@ -278,8 +285,8 @@ av_cold int ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg) if (!band->bufs[2]) return AVERROR(ENOMEM); } - - planes[p].bands[0].blk_vlc.cust_desc.num_rows = 0; /* reset custom vlc */ + /* reset custom vlc */ + planes[p].bands[0].blk_vlc.cust_desc.num_rows = 0; } } @@ -827,7 +834,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]; @@ -840,7 +848,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); } } @@ -896,10 +905,13 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, //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*/) { + /* 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 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) From 73d5d7acb0e01142fe6935196f57000f26717d30 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Wed, 3 Jul 2013 14:55:50 +0200 Subject: [PATCH 06/12] indeo: reject negative array indexes Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 6a10142faa1cca8ba2bfe51b970754f62d60f320) Signed-off-by: Luca Barbato --- libavcodec/ivi_common.c | 42 ++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c index 0caefe1ed6..815a5cb112 100644 --- a/libavcodec/ivi_common.c +++ b/libavcodec/ivi_common.c @@ -44,6 +44,20 @@ 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(ivi_mc_func mc, int16_t *buf, const int16_t *ref_buf, + int offs, int mv_x, int mv_y, uint32_t pitch, + int mc_type) +{ + int ref_offs = offs + mv_y * pitch + mv_x; + + if (offs < 0 || ref_offs < 0 || !ref_buf) + return AVERROR_INVALIDDATA; + + mc(buf + offs, ref_buf + ref_offs, pitch, mc_type); + + return 0; +} + /** * Reverse "nbits" bits of the value "val" and return the result * in the least significant bits. @@ -444,7 +458,7 @@ static int ivi_decode_coded_blocks(GetBitContext *gb, IVIBandDesc *band, /* de-zigzag and dequantize */ scan_pos += run; - if (scan_pos >= num_coeffs) + if (scan_pos >= num_coeffs || scan_pos < 0) break; pos = band->scan[scan_pos]; @@ -459,7 +473,7 @@ static int ivi_decode_coded_blocks(GetBitContext *gb, IVIBandDesc *band, col_flags[pos & col_mask] |= !!val; } - if (scan_pos >= num_coeffs && sym != rvmap->eob_sym) + 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 */ @@ -475,9 +489,8 @@ static int ivi_decode_coded_blocks(GetBitContext *gb, IVIBandDesc *band, /* apply motion compensation */ if (!is_intra) - mc(band->buf + offs, - band->ref_buf + offs + mv_y * band->pitch + mv_x, - band->pitch, mc_type); + return ivi_mc(mc, band->buf, band->ref_buf, offs, mv_x, mv_y, + band->pitch, mc_type); return 0; } @@ -575,10 +588,12 @@ static int ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, if (band->dc_transform) 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); + } else { + ret = ivi_mc(mc_no_delta_func, band->buf, band->ref_buf, + buf_offs, mv_x, mv_y, band->pitch, mc_type); + if (ret < 0) + return ret; + } } cbp >>= 1; @@ -603,7 +618,7 @@ 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; @@ -681,9 +696,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(mc_no_delta_func, band->buf, band->ref_buf, + offs, mv_x, mv_y, band->pitch, mc_type); + if (ret < 0) + return ret; } } } else { From 1c2bd6fe5f962b32ca48e6a6fa4e179d02e6bf90 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Mon, 1 Jul 2013 03:04:15 +0200 Subject: [PATCH 07/12] kmvc: use fixed sized arrays in the context Avoid some boilerplate code to dynamically allocate and then free the buffers. (cherry picked from commit 8f689770548c86151071ef976cf9b6998ba21c2a) Signed-off-by: Reinhard Tartler Conflicts: libavcodec/kmvc.c --- libavcodec/kmvc.c | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/libavcodec/kmvc.c b/libavcodec/kmvc.c index d9fbbb0d71..1bfc0da802 100644 --- a/libavcodec/kmvc.c +++ b/libavcodec/kmvc.c @@ -47,7 +47,7 @@ typedef struct KmvcContext { int palsize; uint32_t pal[MAX_PALSIZE]; uint8_t *cur, *prev; - uint8_t *frm0, *frm1; + uint8_t frm0[320 * 200], frm1[320 * 200]; GetByteContext g; } KmvcContext; @@ -369,8 +369,6 @@ static av_cold int decode_init(AVCodecContext * avctx) return -1; } - c->frm0 = av_mallocz(320 * 200); - c->frm1 = av_mallocz(320 * 200); c->cur = c->frm0; c->prev = c->frm1; @@ -404,30 +402,12 @@ static av_cold int decode_init(AVCodecContext * avctx) return 0; } - - -/* - * Uninit kmvc decoder - */ -static av_cold int decode_end(AVCodecContext * avctx) -{ - KmvcContext *const c = avctx->priv_data; - - av_freep(&c->frm0); - av_freep(&c->frm1); - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - - return 0; -} - AVCodec ff_kmvc_decoder = { .name = "kmvc", .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_KMVC, .priv_data_size = sizeof(KmvcContext), .init = decode_init, - .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("Karl Morton's video codec"), From 258eea3f2e0db2c8d46982b766b7965c40095a28 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Mon, 1 Jul 2013 03:05:41 +0200 Subject: [PATCH 08/12] kmvc: Clip pixel position to valid range Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 4e7f0b082d8c4b360312216b9241bec65ff63b35) Signed-off-by: Reinhard Tartler --- libavcodec/kmvc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/kmvc.c b/libavcodec/kmvc.c index 1bfc0da802..e3dcd076a5 100644 --- a/libavcodec/kmvc.c +++ b/libavcodec/kmvc.c @@ -30,6 +30,7 @@ #include "avcodec.h" #include "bytestream.h" #include "internal.h" +#include "libavutil/common.h" #define KMVC_KEYFRAME 0x80 #define KMVC_PALETTE 0x40 @@ -56,7 +57,7 @@ typedef struct BitBuf { int bitbuf; } BitBuf; -#define BLK(data, x, y) data[(x) + (y) * 320] +#define BLK(data, x, y) data[av_clip((x) + (y) * 320, 0, 320 * 200 -1)] #define kmvc_init_getbits(bb, g) bb.bits = 7; bb.bitbuf = bytestream2_get_byte(g); From 9aaca159bd220582c698f13d081a455f398c9975 Mon Sep 17 00:00:00 2001 From: Reinhard Tartler Date: Sat, 6 Jul 2013 13:20:57 +0200 Subject: [PATCH 09/12] Update Changelog --- Changelog | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Changelog b/Changelog index 754e4168b6..4cd63c823a 100644 --- a/Changelog +++ b/Changelog @@ -2,6 +2,9 @@ Entries are sorted chronologically from oldest to youngest within each release, releases are sorted from youngest to oldest. version 9.8: +- kmvc: Clip pixel position to valid range +- kmvc: Use fixed sized arrays in the context +- indeo: Reject negative array indexes - indeo: Check for reference when inheriting motion vectors - indeo: Properly forward the error codes - mjpeg: Check the unescaped size for overflows From c2c9b7297fe6ee95788c27728b0073e38e33b94d Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Sat, 27 Jul 2013 15:48:41 +0200 Subject: [PATCH 10/12] avidec: Let the inner dv demuxer take care of discarding (cherry picked from commit c8f0b20b4a6bb6691928789d83e4b) CC: libav-stable@libav.org --- libavformat/avidec.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libavformat/avidec.c b/libavformat/avidec.c index a3af5cf2de..ee341c21b6 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -920,9 +920,12 @@ start_sync: } - if( (st->discard >= AVDISCARD_DEFAULT && size==0) - /*|| (st->discard >= AVDISCARD_NONKEY && !(pkt->flags & AV_PKT_FLAG_KEY))*/ //FIXME needs a little reordering - || st->discard >= AVDISCARD_ALL){ + if (!avi->dv_demux && + ((st->discard >= AVDISCARD_DEFAULT && size==0) /* || + //FIXME needs a little reordering + (st->discard >= AVDISCARD_NONKEY && + !(pkt->flags & AV_PKT_FLAG_KEY)) */ + || st->discard >= AVDISCARD_ALL)) { if (!exit_early) { ast->frame_offset += get_duration(ast, size); } From 3f5824aa18aa7b18016701123efc7e1714d56001 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 4 Aug 2013 18:57:39 +0200 Subject: [PATCH 11/12] avconv: do not use lavfi direct rendering with -deinterlace -deinterlace allocates a temporary buffer that is freed immediately after the frame is sent to lavfi, which results in use after free. Disable direct rendering when -deinterlace is used. CC:libav-stable@libav.org Bug-id: 479 --- avconv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avconv.c b/avconv.c index dd998ab40c..6544fc6fb7 100644 --- a/avconv.c +++ b/avconv.c @@ -1215,7 +1215,7 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) } for (i = 0; i < ist->nb_filters; i++) { - if (ist->st->codec->codec->capabilities & CODEC_CAP_DR1) { + if (ist->st->codec->codec->capabilities & CODEC_CAP_DR1 && !do_deinterlace) { FrameBuffer *buf = decoded_frame->opaque; AVFilterBufferRef *fb = avfilter_get_video_buffer_ref_from_arrays( decoded_frame->data, decoded_frame->linesize, From fa6eef4210c2fd7f7324d558b09311c75987a31e Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Mon, 24 Jun 2013 18:12:24 +0200 Subject: [PATCH 12/12] wtv: Mark attachment with a negative stream id A sid 0 would be mismatched to the attachment. Prevent NULL pointer dereference. Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit f5e646a00ac21e500dae4bcceded790a0fbc5246) Signed-off-by: Luca Barbato --- libavformat/wtv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavformat/wtv.c b/libavformat/wtv.c index 2e5d39cff2..1811e4645c 100644 --- a/libavformat/wtv.c +++ b/libavformat/wtv.c @@ -502,6 +502,7 @@ static void get_attachment(AVFormatContext *s, AVIOContext *pb, int length) st->codec->codec_id = AV_CODEC_ID_MJPEG; st->codec->codec_type = AVMEDIA_TYPE_ATTACHMENT; st->codec->extradata = av_mallocz(filesize); + st->id = -1; if (!st->codec->extradata) goto done; st->codec->extradata_size = filesize;