Note that this will not work in most cases with avconv and avplay due to the
AVCODEC_MAX_AUDIO_FRAME_SIZE limit, but it will decode correctly if given a
large enough output buffer.
---
 libavcodec/tta.c |   25 +++++++++++++++++++------
 1 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/libavcodec/tta.c b/libavcodec/tta.c
index 534eb1f..bf04fb7 100644
--- a/libavcodec/tta.c
+++ b/libavcodec/tta.c
@@ -227,10 +227,12 @@ static av_cold int tta_decode_init(AVCodecContext * avctx)
         switch(s->bps) {
         case 2:
             avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+            avctx->bits_per_raw_sample = 16;
             break;
         case 3:
-            av_log_missing_feature(avctx, "Unsupported sample format.\n", 0);
-            return AVERROR(EINVAL);
+            avctx->sample_fmt = AV_SAMPLE_FMT_S32;
+            avctx->bits_per_raw_sample = 24;
+            break;
         default:
             av_log(avctx, AV_LOG_ERROR, "Invalid sample format\n");
             return AVERROR(EINVAL);
@@ -258,9 +260,11 @@ static av_cold int tta_decode_init(AVCodecContext * avctx)
             return -1;
         }
 
-        s->decode_buffer = 
av_mallocz(sizeof(int32_t)*s->frame_length*s->channels);
-        if (!s->decode_buffer)
-            return AVERROR(ENOMEM);
+        if (s->bps == 2) {
+            s->decode_buffer = 
av_mallocz(sizeof(int32_t)*s->frame_length*s->channels);
+            if (!s->decode_buffer)
+                return AVERROR(ENOMEM);
+        }
         s->ch_ctx = av_malloc(avctx->channels * sizeof(*s->ch_ctx));
         if (!s->ch_ctx)
             return AVERROR(ENOMEM);
@@ -297,6 +301,10 @@ static int tta_decode_frame(AVCodecContext *avctx,
         return -1;
     }
 
+    // decode directly to output buffer for 24-bit sample format
+    if (s->bps == 3)
+        s->decode_buffer = data;
+
     // init per channel states
     for (i = 0; i < s->channels; i++) {
         s->ch_ctx[i].predictor = 0;
@@ -390,7 +398,12 @@ static int tta_decode_frame(AVCodecContext *avctx,
         for (p = s->decode_buffer; p < s->decode_buffer + (framelen * 
s->channels); p++)
             *samples++ = *p;
     } else {
-        av_log(s->avctx, AV_LOG_ERROR, "Error, only 16bit samples 
supported!\n");
+        // shift samples for 24-bit sample format
+        int32_t *samples = data;
+        for (p = s->decode_buffer; p < s->decode_buffer + (framelen * 
s->channels); p++)
+            *samples++ <<= 8;
+        // reset decode_buffer
+        s->decode_buffer = NULL;
     }
 
     *data_size = out_size;
-- 
1.7.1

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to