Browse code

celtdec: adapt to avcodec_decode_audio4.

Original fix by Michael Niedermayer.
Slightly modified to avoid the now redundant multiplications
and divisions in the main code path.

Nicolas George authored on 2011/12/03 19:52:48
Showing 1 changed files
... ...
@@ -27,7 +27,7 @@
27 27
 struct libcelt_context {
28 28
     CELTMode *mode;
29 29
     CELTDecoder *dec;
30
-    int frame_bytes;
30
+    AVFrame frame;
31 31
     int discard;
32 32
 };
33 33
 
... ...
@@ -64,7 +64,6 @@ static av_cold int libcelt_dec_init(AVCodecContext *c)
64 64
     if (!c->channels || !c->frame_size ||
65 65
         c->frame_size > INT_MAX / sizeof(int16_t) / c->channels)
66 66
         return AVERROR(EINVAL);
67
-    celt->frame_bytes = c->frame_size * c->channels * sizeof(int16_t);
68 67
     celt->mode = celt_mode_create(c->sample_rate, c->frame_size, &err);
69 68
     if (!celt->mode)
70 69
         return ff_celt_error_to_averror(err);
... ...
@@ -80,7 +79,6 @@ static av_cold int libcelt_dec_init(AVCodecContext *c)
80 80
                    "Invalid overlap (%d), ignored.\n", celt->discard);
81 81
             celt->discard = 0;
82 82
         }
83
-        celt->discard *= c->channels * sizeof(int16_t);
84 83
     }
85 84
     if (c->extradata_size >= 8) {
86 85
         unsigned version = AV_RL32(c->extradata + 4);
... ...
@@ -92,6 +90,8 @@ static av_cold int libcelt_dec_init(AVCodecContext *c)
92 92
                    version, lib_version);
93 93
     }
94 94
     c->sample_fmt = AV_SAMPLE_FMT_S16;
95
+    avcodec_get_frame_defaults(&celt->frame);
96
+    c->coded_frame = &celt->frame;
95 97
     return 0;
96 98
 }
97 99
 
... ...
@@ -104,23 +104,31 @@ static av_cold int libcelt_dec_close(AVCodecContext *c)
104 104
     return 0;
105 105
 }
106 106
 
107
-static int libcelt_dec_decode(AVCodecContext *c, void *pcm, int *pcm_size,
108
-                              AVPacket *pkt)
107
+static int libcelt_dec_decode(AVCodecContext *c, void *frame,
108
+                              int *got_frame_ptr, AVPacket *pkt)
109 109
 {
110 110
     struct libcelt_context *celt = c->priv_data;
111 111
     int err;
112
+    int16_t *pcm;
112 113
 
113
-    if (*pcm_size < celt->frame_bytes)
114
-        return AVERROR(ENOBUFS);
114
+    celt->frame.nb_samples = c->frame_size;
115
+    err = c->get_buffer(c, &celt->frame);
116
+    if (err < 0) {
117
+        av_log(c, AV_LOG_ERROR, "get_buffer() failed\n");
118
+        return err;
119
+    }
120
+    pcm = (int16_t *)celt->frame.data[0];
115 121
     err = celt_decode(celt->dec, pkt->data, pkt->size, pcm, c->frame_size);
116 122
     if (err < 0)
117 123
         return ff_celt_error_to_averror(err);
118
-    *pcm_size = celt->frame_bytes;
119 124
     if (celt->discard) {
120
-        *pcm_size = celt->frame_bytes - celt->discard;
121
-        memmove(pcm, (char *)pcm + celt->discard, *pcm_size);
125
+        celt->frame.nb_samples -= celt->discard;
126
+        memmove(pcm, pcm + celt->discard * c->channels,
127
+                celt->frame.nb_samples * c->channels * sizeof(int16_t));
122 128
         celt->discard = 0;
123 129
     }
130
+    *got_frame_ptr = 1;
131
+    *(AVFrame *)frame = celt->frame;
124 132
     return pkt->size;
125 133
 }
126 134
 
... ...
@@ -132,6 +140,6 @@ AVCodec ff_libcelt_decoder = {
132 132
     .init           = libcelt_dec_init,
133 133
     .close          = libcelt_dec_close,
134 134
     .decode         = libcelt_dec_decode,
135
-    .capabilities   = 0,
135
+    .capabilities   = CODEC_CAP_DR1,
136 136
     .long_name      = NULL_IF_CONFIG_SMALL("Xiph CELT decoder using libcelt"),
137 137
 };