summaryrefslogtreecommitdiff
path: root/libavcodec/aic.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavcodec/aic.c')
-rw-r--r--libavcodec/aic.c74
1 files changed, 44 insertions, 30 deletions
diff --git a/libavcodec/aic.c b/libavcodec/aic.c
index de9d7de91b..9c6f806655 100644
--- a/libavcodec/aic.c
+++ b/libavcodec/aic.c
@@ -3,30 +3,30 @@
*
* Copyright (c) 2013 Konstantin Shishkov
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <inttypes.h>
#include "avcodec.h"
-#include "bitstream.h"
#include "bytestream.h"
-#include "golomb.h"
#include "internal.h"
+#include "get_bits.h"
+#include "golomb.h"
#include "idctdsp.h"
#include "thread.h"
#include "unary.h"
@@ -153,6 +153,7 @@ typedef struct AICContext {
int16_t *data_ptr[NUM_BANDS];
DECLARE_ALIGNED(16, int16_t, block)[64];
+ DECLARE_ALIGNED(16, uint8_t, quant_matrix)[64];
} AICContext;
static int aic_decode_header(AICContext *ctx, const uint8_t *src, int size)
@@ -191,41 +192,42 @@ static int aic_decode_header(AICContext *ctx, const uint8_t *src, int size)
#define GET_CODE(val, type, add_bits) \
do { \
if (type) \
- val = get_ue_golomb(bc); \
+ val = get_ue_golomb(gb); \
else \
- val = get_unary(bc, 1, 31); \
+ val = get_unary(gb, 1, 31); \
if (add_bits) \
- val = (val << add_bits) + bitstream_read(bc, add_bits); \
+ val = (val << add_bits) + get_bits(gb, add_bits); \
} while (0)
-static int aic_decode_coeffs(BitstreamContext *bc, int16_t *dst,
+static int aic_decode_coeffs(GetBitContext *gb, int16_t *dst,
int band, int slice_width, int force_chroma)
{
int has_skips, coeff_type, coeff_bits, skip_type, skip_bits;
const int num_coeffs = aic_num_band_coeffs[band];
const uint8_t *scan = aic_scan[band | force_chroma];
- int mb, idx, val;
+ int mb, idx;
+ unsigned val;
- has_skips = bitstream_read_bit(bc);
- coeff_type = bitstream_read_bit(bc);
- coeff_bits = bitstream_read(bc, 3);
+ has_skips = get_bits1(gb);
+ coeff_type = get_bits1(gb);
+ coeff_bits = get_bits(gb, 3);
if (has_skips) {
- skip_type = bitstream_read_bit(bc);
- skip_bits = bitstream_read(bc, 3);
+ skip_type = get_bits1(gb);
+ skip_bits = get_bits(gb, 3);
for (mb = 0; mb < slice_width; mb++) {
idx = -1;
do {
GET_CODE(val, skip_type, skip_bits);
- if (val < 0)
+ if (val >= 0x10000)
return AVERROR_INVALIDDATA;
idx += val + 1;
if (idx >= num_coeffs)
break;
GET_CODE(val, coeff_type, coeff_bits);
val++;
- if (val >= 0x10000 || val < 0)
+ if (val >= 0x10000)
return AVERROR_INVALIDDATA;
dst[scan[idx]] = val;
} while (idx < num_coeffs - 1);
@@ -235,7 +237,7 @@ static int aic_decode_coeffs(BitstreamContext *bc, int16_t *dst,
for (mb = 0; mb < slice_width; mb++) {
for (idx = 0; idx < num_coeffs; idx++) {
GET_CODE(val, coeff_type, coeff_bits);
- if (val >= 0x10000 || val < 0)
+ if (val >= 0x10000)
return AVERROR_INVALIDDATA;
dst[scan[idx]] = val;
}
@@ -287,7 +289,7 @@ static void recombine_block_il(int16_t *dst, const uint8_t *scan,
}
}
-static void unquant_block(int16_t *block, int q)
+static void unquant_block(int16_t *block, int q, uint8_t *quant_matrix)
{
int i;
@@ -295,7 +297,7 @@ static void unquant_block(int16_t *block, int q)
int val = (uint16_t)block[i];
int sign = val & 1;
- block[i] = (((val >> 1) ^ -sign) * q * aic_quant_matrix[i] >> 4)
+ block[i] = (((val >> 1) ^ -sign) * q * quant_matrix[i] >> 4)
+ sign;
}
}
@@ -303,9 +305,11 @@ static void unquant_block(int16_t *block, int q)
static int aic_decode_slice(AICContext *ctx, int mb_x, int mb_y,
const uint8_t *src, int src_size)
{
- BitstreamContext bc;
+ GetBitContext gb;
int ret, i, mb, blk;
int slice_width = FFMIN(ctx->slice_width, ctx->mb_width - mb_x);
+ int last_row = mb_y && mb_y == ctx->mb_height - 1;
+ int y_pos, c_pos;
uint8_t *Y, *C[2];
uint8_t *dst;
int16_t *base_y = ctx->data_ptr[COEFF_LUMA];
@@ -314,16 +318,24 @@ static int aic_decode_slice(AICContext *ctx, int mb_x, int mb_y,
int16_t *ext_c = ctx->data_ptr[COEFF_CHROMA_EXT];
const int ystride = ctx->frame->linesize[0];
- Y = ctx->frame->data[0] + mb_x * 16 + mb_y * 16 * ystride;
+ if (last_row) {
+ y_pos = (ctx->avctx->height - 16);
+ c_pos = ((ctx->avctx->height+1)/2 - 8);
+ } else {
+ y_pos = mb_y * 16;
+ c_pos = mb_y * 8;
+ }
+
+ Y = ctx->frame->data[0] + mb_x * 16 + y_pos * ystride;
for (i = 0; i < 2; i++)
C[i] = ctx->frame->data[i + 1] + mb_x * 8
- + mb_y * 8 * ctx->frame->linesize[i + 1];
- bitstream_init8(&bc, src, src_size);
+ + c_pos * ctx->frame->linesize[i + 1];
+ init_get_bits(&gb, src, src_size * 8);
memset(ctx->slice_data, 0,
sizeof(*ctx->slice_data) * slice_width * AIC_BAND_COEFFS);
for (i = 0; i < NUM_BANDS; i++)
- if ((ret = aic_decode_coeffs(&bc, ctx->data_ptr[i],
+ if ((ret = aic_decode_coeffs(&gb, ctx->data_ptr[i],
i, slice_width,
!ctx->interlaced)) < 0)
return ret;
@@ -336,7 +348,7 @@ static int aic_decode_slice(AICContext *ctx, int mb_x, int mb_y,
else
recombine_block_il(ctx->block, ctx->scantable.permutated,
&base_y, &ext_y, blk);
- unquant_block(ctx->block, ctx->quant);
+ unquant_block(ctx->block, ctx->quant, ctx->quant_matrix);
ctx->idsp.idct(ctx->block);
if (!ctx->interlaced) {
@@ -353,7 +365,7 @@ static int aic_decode_slice(AICContext *ctx, int mb_x, int mb_y,
for (blk = 0; blk < 2; blk++) {
recombine_block(ctx->block, ctx->scantable.permutated,
&base_c, &ext_c);
- unquant_block(ctx->block, ctx->quant);
+ unquant_block(ctx->block, ctx->quant, ctx->quant_matrix);
ctx->idsp.idct(ctx->block);
ctx->idsp.put_signed_pixels_clamped(ctx->block, C[blk],
ctx->frame->linesize[blk + 1]);
@@ -439,13 +451,15 @@ static av_cold int aic_decode_init(AVCodecContext *avctx)
for (i = 0; i < 64; i++)
scan[i] = i;
ff_init_scantable(ctx->idsp.idct_permutation, &ctx->scantable, scan);
+ for (i = 0; i < 64; i++)
+ ctx->quant_matrix[ctx->idsp.idct_permutation[i]] = aic_quant_matrix[i];
ctx->mb_width = FFALIGN(avctx->width, 16) >> 4;
ctx->mb_height = FFALIGN(avctx->height, 16) >> 4;
ctx->num_x_slices = (ctx->mb_width + 15) >> 4;
ctx->slice_width = 16;
- for (i = 1; i < 32; i++) {
+ for (i = 1; i < ctx->mb_width; i++) {
if (!(ctx->mb_width % i) && (ctx->mb_width / i <= 32)) {
ctx->slice_width = ctx->mb_width / i;
ctx->num_x_slices = i;
@@ -453,7 +467,7 @@ static av_cold int aic_decode_init(AVCodecContext *avctx)
}
}
- ctx->slice_data = av_malloc(ctx->slice_width * AIC_BAND_COEFFS
+ ctx->slice_data = av_malloc_array(ctx->slice_width, AIC_BAND_COEFFS
* sizeof(*ctx->slice_data));
if (!ctx->slice_data) {
av_log(avctx, AV_LOG_ERROR, "Error allocating slice buffer\n");