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