... | ... |
@@ -22,6 +22,8 @@ |
22 | 22 |
#include "avcodec.h" |
23 | 23 |
#include "libavutil/avstring.h" |
24 | 24 |
#include "libavutil/opt.h" |
25 |
+#include "audio_frame_queue.h" |
|
26 |
+#include "internal.h" |
|
25 | 27 |
|
26 | 28 |
static void amr_decode_fix_avctx(AVCodecContext *avctx) |
27 | 29 |
{ |
... | ... |
@@ -85,6 +87,7 @@ typedef struct AMRContext { |
85 | 85 |
int enc_mode; |
86 | 86 |
int enc_dtx; |
87 | 87 |
int enc_last_frame; |
88 |
+ AudioFrameQueue afq; |
|
88 | 89 |
} AMRContext; |
89 | 90 |
|
90 | 91 |
static const AVOption options[] = { |
... | ... |
@@ -196,9 +199,12 @@ static av_cold int amr_nb_encode_init(AVCodecContext *avctx) |
196 | 196 |
|
197 | 197 |
avctx->frame_size = 160; |
198 | 198 |
avctx->delay = 50; |
199 |
+ ff_af_queue_init(avctx, &s->afq); |
|
200 |
+#if FF_API_OLD_ENCODE_AUDIO |
|
199 | 201 |
avctx->coded_frame = avcodec_alloc_frame(); |
200 | 202 |
if (!avctx->coded_frame) |
201 | 203 |
return AVERROR(ENOMEM); |
204 |
+#endif |
|
202 | 205 |
|
203 | 206 |
s->enc_state = Encoder_Interface_init(s->enc_dtx); |
204 | 207 |
if (!s->enc_state) { |
... | ... |
@@ -218,38 +224,49 @@ static av_cold int amr_nb_encode_close(AVCodecContext *avctx) |
218 | 218 |
AMRContext *s = avctx->priv_data; |
219 | 219 |
|
220 | 220 |
Encoder_Interface_exit(s->enc_state); |
221 |
+ ff_af_queue_close(&s->afq); |
|
222 |
+#if FF_API_OLD_ENCODE_AUDIO |
|
221 | 223 |
av_freep(&avctx->coded_frame); |
224 |
+#endif |
|
222 | 225 |
return 0; |
223 | 226 |
} |
224 | 227 |
|
225 |
-static int amr_nb_encode_frame(AVCodecContext *avctx, |
|
226 |
- unsigned char *frame/*out*/, |
|
227 |
- int buf_size, void *data/*in*/) |
|
228 |
+static int amr_nb_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, |
|
229 |
+ const AVFrame *frame, int *got_packet_ptr) |
|
228 | 230 |
{ |
229 | 231 |
AMRContext *s = avctx->priv_data; |
230 |
- int written; |
|
232 |
+ int written, ret; |
|
231 | 233 |
int16_t *flush_buf = NULL; |
232 |
- const int16_t *samples = data; |
|
234 |
+ const int16_t *samples = frame ? (const int16_t *)frame->data[0] : NULL; |
|
233 | 235 |
|
234 | 236 |
if (s->enc_bitrate != avctx->bit_rate) { |
235 | 237 |
s->enc_mode = get_bitrate_mode(avctx->bit_rate, avctx); |
236 | 238 |
s->enc_bitrate = avctx->bit_rate; |
237 | 239 |
} |
238 | 240 |
|
239 |
- if (data) { |
|
240 |
- if (avctx->frame_size < 160) { |
|
241 |
- flush_buf = av_mallocz(160 * sizeof(*flush_buf)); |
|
241 |
+ if ((ret = ff_alloc_packet(avpkt, 32))) { |
|
242 |
+ av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n"); |
|
243 |
+ return ret; |
|
244 |
+ } |
|
245 |
+ |
|
246 |
+ if (frame) { |
|
247 |
+ if (frame->nb_samples < avctx->frame_size) { |
|
248 |
+ flush_buf = av_mallocz(avctx->frame_size * sizeof(*flush_buf)); |
|
242 | 249 |
if (!flush_buf) |
243 | 250 |
return AVERROR(ENOMEM); |
244 |
- memcpy(flush_buf, samples, avctx->frame_size * sizeof(*flush_buf)); |
|
251 |
+ memcpy(flush_buf, samples, frame->nb_samples * sizeof(*flush_buf)); |
|
245 | 252 |
samples = flush_buf; |
246 |
- if (avctx->frame_size < 110) |
|
253 |
+ if (frame->nb_samples < avctx->frame_size - avctx->delay) |
|
247 | 254 |
s->enc_last_frame = -1; |
248 | 255 |
} |
256 |
+ if ((ret = ff_af_queue_add(&s->afq, frame) < 0)) { |
|
257 |
+ av_freep(&flush_buf); |
|
258 |
+ return ret; |
|
259 |
+ } |
|
249 | 260 |
} else { |
250 | 261 |
if (s->enc_last_frame < 0) |
251 | 262 |
return 0; |
252 |
- flush_buf = av_mallocz(160 * sizeof(*flush_buf)); |
|
263 |
+ flush_buf = av_mallocz(avctx->frame_size * sizeof(*flush_buf)); |
|
253 | 264 |
if (!flush_buf) |
254 | 265 |
return AVERROR(ENOMEM); |
255 | 266 |
samples = flush_buf; |
... | ... |
@@ -257,12 +274,18 @@ static int amr_nb_encode_frame(AVCodecContext *avctx, |
257 | 257 |
} |
258 | 258 |
|
259 | 259 |
written = Encoder_Interface_Encode(s->enc_state, s->enc_mode, samples, |
260 |
- frame, 0); |
|
260 |
+ avpkt->data, 0); |
|
261 | 261 |
av_dlog(avctx, "amr_nb_encode_frame encoded %u bytes, bitrate %u, first byte was %#02x\n", |
262 | 262 |
written, s->enc_mode, frame[0]); |
263 | 263 |
|
264 |
+ /* Get the next frame pts/duration */ |
|
265 |
+ ff_af_queue_remove(&s->afq, avctx->frame_size, &avpkt->pts, |
|
266 |
+ &avpkt->duration); |
|
267 |
+ |
|
268 |
+ avpkt->size = written; |
|
269 |
+ *got_packet_ptr = 1; |
|
264 | 270 |
av_freep(&flush_buf); |
265 |
- return written; |
|
271 |
+ return 0; |
|
266 | 272 |
} |
267 | 273 |
|
268 | 274 |
AVCodec ff_libopencore_amrnb_encoder = { |
... | ... |
@@ -271,7 +294,7 @@ AVCodec ff_libopencore_amrnb_encoder = { |
271 | 271 |
.id = CODEC_ID_AMR_NB, |
272 | 272 |
.priv_data_size = sizeof(AMRContext), |
273 | 273 |
.init = amr_nb_encode_init, |
274 |
- .encode = amr_nb_encode_frame, |
|
274 |
+ .encode2 = amr_nb_encode_frame, |
|
275 | 275 |
.close = amr_nb_encode_close, |
276 | 276 |
.capabilities = CODEC_CAP_DELAY | CODEC_CAP_SMALL_LAST_FRAME, |
277 | 277 |
.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE}, |