]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/metasound.c
mjpegdec: Properly fail on malloc failure
[ffmpeg] / libavcodec / metasound.c
index b1245368f31b5a0c36dec9ab39db43b8f20cdc40..dbb2a63e3ec48972fc2618c2ccc9844e9d171973 100644 (file)
@@ -21,6 +21,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <inttypes.h>
 #include <math.h>
 #include <stdint.h>
 
@@ -163,73 +164,76 @@ static void read_cb_data(TwinVQContext *tctx, GetBitContext *gb,
 static int metasound_read_bitstream(AVCodecContext *avctx, TwinVQContext *tctx,
                                     const uint8_t *buf, int buf_size)
 {
-    TwinVQFrameData     *bits = &tctx->bits;
+    TwinVQFrameData     *bits;
     const TwinVQModeTab *mtab = tctx->mtab;
     int channels              = tctx->avctx->channels;
     int sub;
     GetBitContext gb;
     int i, j, k;
 
-    if (buf_size * 8 < avctx->bit_rate * mtab->size / avctx->sample_rate) {
-        av_log(avctx, AV_LOG_ERROR,
-               "Frame too small (%d bytes). Truncated file?\n", buf_size);
-        return AVERROR(EINVAL);
-    }
-
     init_get_bits(&gb, buf, buf_size * 8);
 
-    bits->window_type = get_bits(&gb, TWINVQ_WINDOW_TYPE_BITS);
+    for (tctx->cur_frame = 0; tctx->cur_frame < tctx->frames_per_packet;
+         tctx->cur_frame++) {
+        bits = tctx->bits + tctx->cur_frame;
 
-    if (bits->window_type > 8) {
-        av_log(avctx, AV_LOG_ERROR, "Invalid window type, broken sample?\n");
-        return AVERROR_INVALIDDATA;
-    }
+        bits->window_type = get_bits(&gb, TWINVQ_WINDOW_TYPE_BITS);
 
-    bits->ftype = ff_twinvq_wtype_to_ftype_table[tctx->bits.window_type];
+        if (bits->window_type > 8) {
+            av_log(avctx, AV_LOG_ERROR, "Invalid window type, broken sample?\n");
+            return AVERROR_INVALIDDATA;
+        }
 
-    sub = mtab->fmode[bits->ftype].sub;
+        bits->ftype = ff_twinvq_wtype_to_ftype_table[tctx->bits[tctx->cur_frame].window_type];
 
-    if (bits->ftype != TWINVQ_FT_SHORT)
-        get_bits(&gb, 2);
+        sub = mtab->fmode[bits->ftype].sub;
 
-    read_cb_data(tctx, &gb, bits->main_coeffs, bits->ftype);
+        if (bits->ftype != TWINVQ_FT_SHORT && !tctx->is_6kbps)
+            get_bits(&gb, 2);
 
-    for (i = 0; i < channels; i++)
-        for (j = 0; j < sub; j++)
-            for (k = 0; k < mtab->fmode[bits->ftype].bark_n_coef; k++)
-                bits->bark1[i][j][k] =
-                    get_bits(&gb, mtab->fmode[bits->ftype].bark_n_bit);
+        read_cb_data(tctx, &gb, bits->main_coeffs, bits->ftype);
 
-    for (i = 0; i < channels; i++)
-        for (j = 0; j < sub; j++)
-            bits->bark_use_hist[i][j] = get_bits1(&gb);
+        for (i = 0; i < channels; i++)
+            for (j = 0; j < sub; j++)
+                for (k = 0; k < mtab->fmode[bits->ftype].bark_n_coef; k++)
+                    bits->bark1[i][j][k] =
+                        get_bits(&gb, mtab->fmode[bits->ftype].bark_n_bit);
 
-    if (bits->ftype == TWINVQ_FT_LONG) {
         for (i = 0; i < channels; i++)
-            bits->gain_bits[i] = get_bits(&gb, TWINVQ_GAIN_BITS);
-    } else {
-        for (i = 0; i < channels; i++) {
-            bits->gain_bits[i] = get_bits(&gb, TWINVQ_GAIN_BITS);
             for (j = 0; j < sub; j++)
-                bits->sub_gain_bits[i * sub + j] =
-                    get_bits(&gb, TWINVQ_SUB_GAIN_BITS);
+                bits->bark_use_hist[i][j] = get_bits1(&gb);
+
+        if (bits->ftype == TWINVQ_FT_LONG) {
+            for (i = 0; i < channels; i++)
+                bits->gain_bits[i] = get_bits(&gb, TWINVQ_GAIN_BITS);
+        } else {
+            for (i = 0; i < channels; i++) {
+                bits->gain_bits[i] = get_bits(&gb, TWINVQ_GAIN_BITS);
+                for (j = 0; j < sub; j++)
+                    bits->sub_gain_bits[i * sub + j] =
+                        get_bits(&gb, TWINVQ_SUB_GAIN_BITS);
+            }
         }
-    }
 
-    for (i = 0; i < channels; i++) {
-        bits->lpc_hist_idx[i] = get_bits(&gb, mtab->lsp_bit0);
-        bits->lpc_idx1[i]     = get_bits(&gb, mtab->lsp_bit1);
+        for (i = 0; i < channels; i++) {
+            bits->lpc_hist_idx[i] = get_bits(&gb, mtab->lsp_bit0);
+            bits->lpc_idx1[i]     = get_bits(&gb, mtab->lsp_bit1);
 
-        for (j = 0; j < mtab->lsp_split; j++)
-            bits->lpc_idx2[i][j] = get_bits(&gb, mtab->lsp_bit2);
-    }
+            for (j = 0; j < mtab->lsp_split; j++)
+                bits->lpc_idx2[i][j] = get_bits(&gb, mtab->lsp_bit2);
+        }
 
-    if (bits->ftype == TWINVQ_FT_LONG) {
-        read_cb_data(tctx, &gb, bits->ppc_coeffs, 3);
-        for (i = 0; i < channels; i++) {
-            bits->p_coef[i] = get_bits(&gb, mtab->ppc_period_bit);
-            bits->g_coef[i] = get_bits(&gb, mtab->pgain_bit);
+        if (bits->ftype == TWINVQ_FT_LONG) {
+            read_cb_data(tctx, &gb, bits->ppc_coeffs, 3);
+            for (i = 0; i < channels; i++) {
+                bits->p_coef[i] = get_bits(&gb, mtab->ppc_period_bit);
+                bits->g_coef[i] = get_bits(&gb, mtab->pgain_bit);
+            }
         }
+
+        // subframes are aligned to nibbles
+        if (get_bits_count(&gb) & 3)
+            skip_bits(&gb, 4 - (get_bits_count(&gb) & 3));
     }
 
     return 0;
@@ -280,7 +284,7 @@ static av_cold int metasound_decode_init(AVCodecContext *avctx)
 
     for (;;) {
         if (!props->tag) {
-            av_log(avctx, AV_LOG_ERROR, "Could not find tag %08X\n", tag);
+            av_log(avctx, AV_LOG_ERROR, "Could not find tag %08"PRIX32"\n", tag);
             return AVERROR_INVALIDDATA;
         }
         if (props->tag == tag) {
@@ -304,22 +308,58 @@ static av_cold int metasound_decode_init(AVCodecContext *avctx)
     ibps = avctx->bit_rate / (1000 * avctx->channels);
 
     switch ((avctx->channels << 16) + (isampf << 8) + ibps) {
+    case (1 << 16) + ( 8 << 8) +  6:
+        tctx->mtab = &ff_metasound_mode0806;
+        break;
+    case (2 << 16) + ( 8 << 8) +  6:
+        tctx->mtab = &ff_metasound_mode0806s;
+        break;
     case (1 << 16) + ( 8 << 8) +  8:
         tctx->mtab = &ff_metasound_mode0808;
         break;
+    case (2 << 16) + ( 8 << 8) +  8:
+        tctx->mtab = &ff_metasound_mode0808s;
+        break;
+    case (1 << 16) + (11 << 8) + 10:
+        tctx->mtab = &ff_metasound_mode1110;
+        break;
+    case (2 << 16) + (11 << 8) + 10:
+        tctx->mtab = &ff_metasound_mode1110s;
+        break;
     case (1 << 16) + (16 << 8) + 16:
         tctx->mtab = &ff_metasound_mode1616;
         break;
+    case (2 << 16) + (16 << 8) + 16:
+        tctx->mtab = &ff_metasound_mode1616s;
+        break;
+    case (1 << 16) + (22 << 8) + 24:
+        tctx->mtab = &ff_metasound_mode2224;
+        break;
+    case (2 << 16) + (22 << 8) + 24:
+        tctx->mtab = &ff_metasound_mode2224s;
+        break;
     case (1 << 16) + (44 << 8) + 32:
         tctx->mtab = &ff_metasound_mode4432;
         break;
+    case (2 << 16) + (44 << 8) + 32:
+        tctx->mtab = &ff_metasound_mode4432s;
+        break;
+    case (1 << 16) + (44 << 8) + 40:
+        tctx->mtab = &ff_metasound_mode4440;
+        break;
+    case (2 << 16) + (44 << 8) + 40:
+        tctx->mtab = &ff_metasound_mode4440s;
+        break;
+    case (1 << 16) + (44 << 8) + 48:
+        tctx->mtab = &ff_metasound_mode4448;
+        break;
     case (2 << 16) + (44 << 8) + 48:
         tctx->mtab = &ff_metasound_mode4448s;
         break;
     default:
         av_log(avctx, AV_LOG_ERROR,
                "This version does not support %d kHz - %d kbit/s/ch mode.\n",
-               isampf, isampf);
+               isampf, ibps);
         return AVERROR(ENOSYS);
     }
 
@@ -327,6 +367,9 @@ static av_cold int metasound_decode_init(AVCodecContext *avctx)
     tctx->read_bitstream = metasound_read_bitstream;
     tctx->dec_bark_env   = dec_bark_env;
     tctx->decode_ppc     = decode_ppc;
+    tctx->frame_size     = avctx->bit_rate * tctx->mtab->size
+                                           / avctx->sample_rate;
+    tctx->is_6kbps       = ibps == 6;
 
     return ff_twinvq_decode_init(avctx);
 }
@@ -340,7 +383,7 @@ AVCodec ff_metasound_decoder = {
     .init           = metasound_decode_init,
     .close          = ff_twinvq_decode_close,
     .decode         = ff_twinvq_decode_frame,
-    .capabilities   = CODEC_CAP_DR1,
+    .capabilities   = AV_CODEC_CAP_DR1,
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
 };