#include "internal.h"
#include "golomb.h"
#include "dirac_arith.h"
+#include "dirac_vlc.h"
#include "mpeg12data.h"
#include "libavcodec/mpegvideo.h"
#include "mpegvideoencdsp.h"
SubBand band[MAX_DWT_LEVELS][4];
} Plane;
+/* Used by Low Delay and High Quality profiles */
+typedef struct DiracSlice {
+ GetBitContext gb;
+ int slice_x;
+ int slice_y;
+ int bytes;
+} DiracSlice;
+
typedef struct DiracContext {
AVCodecContext *avctx;
MpegvideoEncDSPContext mpvencdsp;
VideoDSPContext vdsp;
DiracDSPContext diracdsp;
+ DiracGolombLUT *reader_ctx;
DiracVersionInfo version;
GetBitContext gb;
AVDiracSeqHeader seq;
int threads_num_buf; /* Current # of buffers allocated */
int thread_buf_size; /* Each thread has a buffer this size */
+ DiracSlice *slice_params_buf;
+ int slice_params_num_buf;
+
struct {
unsigned width;
unsigned height;
s->threads_num_buf = -1;
s->thread_buf_size = -1;
+ ff_dirac_golomb_reader_init(&s->reader_ctx);
ff_diracdsp_init(&s->diracdsp);
ff_mpegvideoencdsp_init(&s->mpvencdsp, avctx);
ff_videodsp_init(&s->vdsp, 8);
DiracContext *s = avctx->priv_data;
int i;
+ ff_dirac_golomb_reader_end(&s->reader_ctx);
+
dirac_decode_flush(avctx);
for (i = 0; i < MAX_FRAMES; i++)
av_frame_free(&s->all_frames[i].avframe);
av_freep(&s->thread_buf);
+ av_freep(&s->slice_params_buf);
return 0;
}
b->quant = quant;
}
- if (b->quant > DIRAC_MAX_QUANT_INDEX) {
+ if (b->quant > (DIRAC_MAX_QUANT_INDEX - 1)) {
av_log(s->avctx, AV_LOG_ERROR, "Unsupported quant %d\n", b->quant);
b->quant = 0;
return;
uint8_t *buf2 = b2 ? b2->ibuf + top * b2->stride: NULL;
int x, y;
- if (quant > DIRAC_MAX_QUANT_INDEX) {
+ if (quant > (DIRAC_MAX_QUANT_INDEX - 1)) {
av_log(s->avctx, AV_LOG_ERROR, "Unsupported quant %d\n", quant);
return;
}
}
}
-/* Used by Low Delay and High Quality profiles */
-typedef struct DiracSlice {
- GetBitContext gb;
- int slice_x;
- int slice_y;
- int bytes;
-} DiracSlice;
-
-
/**
* Dirac Specification ->
* 13.5.2 Slices. slice(sx,sy)
/* Luma + 2 Chroma planes */
for (i = 0; i < 3; i++) {
- int c, coef_num, coef_par, off = 0;
+ int coef_num, coef_par, off = 0;
int64_t length = s->highquality.size_scaler*get_bits(gb, 8);
- int64_t start = get_bits_count(gb);
- int64_t bits_end = start + 8*length;
+ int64_t bits_end = get_bits_count(gb) + 8*length;
+ const uint8_t *addr = align_get_bits(gb);
- if (bits_end >= INT_MAX) {
+ if (length*8 > get_bits_left(gb)) {
av_log(s->avctx, AV_LOG_ERROR, "end too far away\n");
return AVERROR_INVALIDDATA;
}
coef_num = subband_coeffs(s, slice->slice_x, slice->slice_y, i, coeffs_num);
- if (s->pshift) {
- int32_t *dst = (int32_t *)tmp_buf;
- for (c = 0; c < coef_num; c++)
- dst[c] = dirac_get_se_golomb(gb);
- coef_par = c;
- } else {
- int16_t *dst = (int16_t *)tmp_buf;
- for (c = 0; c < coef_num; c++)
- dst[c] = dirac_get_se_golomb(gb);
- coef_par = c;
- }
+ if (s->pshift)
+ coef_par = ff_dirac_golomb_read_32bit(s->reader_ctx, addr,
+ length, tmp_buf, coef_num);
+ else
+ coef_par = ff_dirac_golomb_read_16bit(s->reader_ctx, addr,
+ length, tmp_buf, coef_num);
if (coef_num > coef_par) {
- const int start_b = coef_par * (4 >> s->pshift);
- const int end_b = coef_num * (4 >> s->pshift);
+ const int start_b = coef_par * (1 << (s->pshift + 1));
+ const int end_b = coef_num * (1 << (s->pshift + 1));
memset(&tmp_buf[start_b], 0, end_b - start_b);
}
SliceCoeffs tmp[MAX_DWT_LEVELS];
int slice_num = 0;
- slices = av_mallocz_array(s->num_x, s->num_y * sizeof(DiracSlice));
- if (!slices)
- return AVERROR(ENOMEM);
+ if (s->slice_params_num_buf != (s->num_x * s->num_y)) {
+ s->slice_params_buf = av_realloc_f(s->slice_params_buf, s->num_x * s->num_y, sizeof(DiracSlice));
+ if (!s->slice_params_buf) {
+ av_log(s->avctx, AV_LOG_ERROR, "slice params buffer allocation failure\n");
+ s->slice_params_num_buf = 0;
+ return AVERROR(ENOMEM);
+ }
+ s->slice_params_num_buf = s->num_x * s->num_y;
+ }
+ slices = s->slice_params_buf;
/* 8 becacuse that's how much the golomb reader could overread junk data
* from another plane/slice at most, and 512 because SIMD */
}
if (bytes >= INT_MAX || bytes*8 > bufsize) {
av_log(s->avctx, AV_LOG_ERROR, "too many bytes\n");
- av_free(slices);
return AVERROR_INVALIDDATA;
}
intra_dc_prediction_8(&s->plane[2].band[0][0]);
}
}
- av_free(slices);
+
return 0;
}
else {
s->num_x = get_interleaved_ue_golomb(gb);
s->num_y = get_interleaved_ue_golomb(gb);
+ if (s->num_x * s->num_y == 0 || s->num_x * (uint64_t)s->num_y > INT_MAX) {
+ av_log(s->avctx,AV_LOG_ERROR,"Invalid numx/y\n");
+ s->num_x = s->num_y = 0;
+ return AVERROR_INVALIDDATA;
+ }
if (s->ld_picture) {
s->lowdelay.bytes.num = get_interleaved_ue_golomb(gb);
s->lowdelay.bytes.den = get_interleaved_ue_golomb(gb);
if (s->low_delay) {
/* [DIRAC_STD] 13.5.1 low_delay_transform_data() */
- for (comp = 0; comp < 3; comp++) {
- Plane *p = &s->plane[comp];
- memset(p->idwt.buf, 0, p->idwt.stride * p->idwt.height);
+ if (!s->hq_picture) {
+ for (comp = 0; comp < 3; comp++) {
+ Plane *p = &s->plane[comp];
+ memset(p->idwt.buf, 0, p->idwt.stride * p->idwt.height);
+ }
}
if (!s->zero_res) {
if ((ret = decode_lowdelay(s)) < 0)
for (j = 0; j < MAX_FRAMES; j++)
if (!s->all_frames[j].avframe->data[0]) {
s->ref_pics[i] = &s->all_frames[j];
- get_buffer_with_edge(s->avctx, s->ref_pics[i]->avframe, AV_GET_BUFFER_FLAG_REF);
+ ret = get_buffer_with_edge(s->avctx, s->ref_pics[i]->avframe, AV_GET_BUFFER_FLAG_REF);
+ if (ret < 0)
+ return ret;
break;
}