]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/sonic.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / libavcodec / sonic.c
index 71641f95ffa78baf085411db3194efd9200a7be6..d42b07de061bd10b6a51f6f0a022398038e6829a 100644 (file)
@@ -44,6 +44,7 @@
 #define RIGHT_SIDE 2
 
 typedef struct SonicContext {
+    AVFrame frame;
     int lossless, decorrelation;
 
     int num_taps, downsampling;
@@ -757,6 +758,9 @@ static av_cold int sonic_decode_init(AVCodecContext *avctx)
     s->channels = avctx->channels;
     s->samplerate = avctx->sample_rate;
 
+    avcodec_get_frame_defaults(&s->frame);
+    avctx->coded_frame = &s->frame;
+
     if (!avctx->extradata)
     {
         av_log(avctx, AV_LOG_ERROR, "No mandatory headers present\n");
@@ -792,6 +796,11 @@ static av_cold int sonic_decode_init(AVCodecContext *avctx)
     s->decorrelation = get_bits(&gb, 2);
 
     s->downsampling = get_bits(&gb, 2);
+    if (!s->downsampling) {
+        av_log(avctx, AV_LOG_ERROR, "invalid downsampling value\n");
+        return AVERROR_INVALIDDATA;
+    }
+
     s->num_taps = (get_bits(&gb, 5)+1)<<5;
     if (get_bits1(&gb)) // XXX FIXME
         av_log(avctx, AV_LOG_INFO, "Custom quant table\n");
@@ -848,18 +857,25 @@ static av_cold int sonic_decode_close(AVCodecContext *avctx)
 }
 
 static int sonic_decode_frame(AVCodecContext *avctx,
-                            void *data, int *data_size,
+                            void *data, int *got_frame_ptr,
                             AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     SonicContext *s = avctx->priv_data;
     GetBitContext gb;
-    int i, quant, ch, j;
-    short *samples = data;
+    int i, quant, ch, j, ret;
+    int16_t *samples;
 
     if (buf_size == 0) return 0;
 
+    s->frame.nb_samples = s->frame_size;
+    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+        return ret;
+    }
+    samples = (int16_t *)s->frame.data[0];
+
 //    av_log(NULL, AV_LOG_INFO, "buf_size: %d\n", buf_size);
 
     init_get_bits(&gb, buf, buf_size*8);
@@ -930,7 +946,8 @@ static int sonic_decode_frame(AVCodecContext *avctx,
 
     align_get_bits(&gb);
 
-    *data_size = s->frame_size * 2;
+    *got_frame_ptr = 1;
+    *(AVFrame*)data = s->frame;
 
     return (get_bits_count(&gb)+7)/8;
 }
@@ -943,6 +960,7 @@ AVCodec ff_sonic_decoder = {
     .init           = sonic_decode_init,
     .close          = sonic_decode_close,
     .decode         = sonic_decode_frame,
+    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_EXPERIMENTAL,
     .long_name = NULL_IF_CONFIG_SMALL("Sonic"),
 };
 #endif /* CONFIG_SONIC_DECODER */
@@ -955,6 +973,7 @@ AVCodec ff_sonic_encoder = {
     .priv_data_size = sizeof(SonicContext),
     .init           = sonic_encode_init,
     .encode         = sonic_encode_frame,
+    .capabilities   = CODEC_CAP_EXPERIMENTAL,
     .close          = sonic_encode_close,
     .long_name = NULL_IF_CONFIG_SMALL("Sonic"),
 };
@@ -968,6 +987,7 @@ AVCodec ff_sonic_ls_encoder = {
     .priv_data_size = sizeof(SonicContext),
     .init           = sonic_encode_init,
     .encode         = sonic_encode_frame,
+    .capabilities   = CODEC_CAP_EXPERIMENTAL,
     .close          = sonic_encode_close,
     .long_name = NULL_IF_CONFIG_SMALL("Sonic lossless"),
 };