]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/diracdec.c
adpcm: fix clipping for yamaha
[ffmpeg] / libavcodec / diracdec.c
index 79136569919cd6b6e1be255dd1366ef03f82dd09..e0604af10384722e69bac64cc740b65b13a6e5fb 100644 (file)
@@ -32,6 +32,7 @@
 #include "internal.h"
 #include "golomb.h"
 #include "dirac_arith.h"
+#include "dirac_vlc.h"
 #include "mpeg12data.h"
 #include "libavcodec/mpegvideo.h"
 #include "mpegvideoencdsp.h"
@@ -120,11 +121,20 @@ typedef struct Plane {
     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;
@@ -165,6 +175,9 @@ typedef struct DiracContext {
     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;
@@ -378,6 +391,7 @@ static av_cold int dirac_decode_init(AVCodecContext *avctx)
     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);
@@ -407,11 +421,14 @@ static av_cold int dirac_decode_end(AVCodecContext *avctx)
     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;
 }
@@ -496,7 +513,7 @@ static inline void codeblock(DiracContext *s, SubBand *b,
         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;
@@ -686,7 +703,7 @@ static void decode_subband(DiracContext *s, GetBitContext *gb, int quant,
     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;
     }
@@ -719,15 +736,6 @@ static void decode_subband(DiracContext *s, GetBitContext *gb, int quant,
     }
 }
 
-/* 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)
@@ -825,33 +833,28 @@ static int decode_hq_slice(DiracContext *s, DiracSlice *slice, uint8_t *tmp_buf)
 
     /* 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);
         }
 
@@ -903,9 +906,16 @@ static int decode_lowdelay(DiracContext *s)
     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 */
@@ -940,7 +950,6 @@ static int decode_lowdelay(DiracContext *s)
                 }
                 if (bytes >= INT_MAX || bytes*8 > bufsize) {
                     av_log(s->avctx, AV_LOG_ERROR, "too many bytes\n");
-                    av_free(slices);
                     return AVERROR_INVALIDDATA;
                 }
 
@@ -997,7 +1006,7 @@ static int decode_lowdelay(DiracContext *s)
             intra_dc_prediction_8(&s->plane[2].band[0][0]);
         }
     }
-    av_free(slices);
+
     return 0;
 }
 
@@ -1217,6 +1226,11 @@ static int dirac_unpack_idwt_params(DiracContext *s)
     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);
@@ -1807,9 +1821,11 @@ static int dirac_decode_frame_internal(DiracContext *s)
 
     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)
@@ -1959,7 +1975,9 @@ static int dirac_decode_picture_header(DiracContext *s)
             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;
                 }