Skip to content

Instantly share code, notes, and snippets.

@moonpfe
Created August 23, 2018 05:05
Show Gist options
  • Save moonpfe/b380e6f82226190ab367570c18125fa8 to your computer and use it in GitHub Desktop.
Save moonpfe/b380e6f82226190ab367570c18125fa8 to your computer and use it in GitHub Desktop.
FFmpeg ADPCM 디코더를 사용하여 오디오 디코딩
From c69c805fc1194e225c3f2ddd2c7429f827d3684e Mon Sep 17 00:00:00 2001
From: InCheol Moon <moonpfe@emstone.com>
Date: Thu, 23 Aug 2018 14:03:55 +0900
Subject: [PATCH] mp4serv: use ffmpeg adpcm decoder
---
src/mp4serv.c | 84 ++++++++++++++++++++-------------------------------
1 file changed, 32 insertions(+), 52 deletions(-)
diff --git a/src/mp4serv.c b/src/mp4serv.c
index 4b84abc30..fcff66c59 100644
--- a/src/mp4serv.c
+++ b/src/mp4serv.c
@@ -123,17 +123,13 @@ struct _Mp4ServClient
struct
{
- EdcAdpcm *decoder;
+ AVCodecContext *decoder;
AVFilterGraph *graph;
AVFilterContext *src;
AVFilterContext *sink;
AVCodecContext *encoder;
AVStream *stream;
- char *buf;
- int buf_len;
- int buf_alloc;
-
int input_sample_fmt;
int input_channel_layout;
AVRational input_time_base;
@@ -558,12 +554,18 @@ mp4serv_init_audio (Mp4ServClient *client,
return;
}
- client->audio.decoder = edc_adpcm_new ();
- client->audio.buf_alloc = 1920 * 2;
- client->audio.buf = g_malloc (client->audio.buf_alloc + AV_INPUT_BUFFER_PADDING_SIZE);
- client->audio.buf_len = 0;
- client->audio.input_sample_fmt = in_par->format;
- client->audio.input_channel_layout = in_par->channel_layout;
+ client->audio.decoder = avcodec_alloc_context3 (decoder);
+ avcodec_parameters_to_context (client->audio.decoder, in_par);
+
+ ret = avcodec_open2 (client->audio.decoder, decoder, NULL);
+ if (ret < 0)
+ {
+ mp4serv_debug (client, "failed to open audio decoder: '%s'(%d)",
+ av_err2str (ret), ret);
+ return;
+ }
+
+ avcodec_parameters_from_context (in_par, client->audio.decoder);
ret = mp4serv_init_audio_resampling_filter (client, in_par);
if (ret < 0)
@@ -579,16 +581,11 @@ mp4serv_deinit_audio (Mp4ServClient *client)
{
if (client->audio.decoder)
{
- edc_adpcm_unref (client->audio.decoder);
+ avcodec_free_context (&client->audio.decoder);
client->audio.decoder = NULL;
}
if (client->audio.graph)
avfilter_graph_free (&client->audio.graph);
-
- g_free (client->audio.buf);
- client->audio.buf = NULL;
- client->audio.buf_alloc = 0;
- client->audio.buf_len = 0;
}
static void
@@ -1345,45 +1342,29 @@ mp4serv_transcode (Mp4ServClient *client,
av_ts2str (packet->duration),
av_ts2str (packet->pos),
packet->size);
- do
+
+ ret = avcodec_send_packet (client->audio.decoder, packet);
+ if (ret < 0 && ret != AVERROR (EAGAIN) && ret != AVERROR_EOF)
+ mp4serv_debug (client, "failed to send audio packet to decoder: '%s'(%d)",
+ av_err2str (ret), ret);
+
+ while (TRUE)
{
- AVFrame *frame;
- int pcm_len;
- int dec_size;
AVRational time_base = { 1, client->audio.sample_rate };
+ AVFrame *frame;
- dec_size = (packet->size - 4) * 4;
- if (dec_size > client->audio.buf_alloc)
- {
- client->audio.buf_alloc = dec_size + AV_INPUT_BUFFER_PADDING_SIZE;
- client->audio.buf = g_realloc (client->audio.buf,
- client->audio.buf_alloc);
- }
+ frame = av_frame_alloc ();
- pcm_len = edc_adpcm_decode (client->audio.decoder,
- (const uint8_t *) packet->data,
- (int16_t *) client->audio.buf,
- packet->size);
- if (pcm_len <= 0)
- break;
+ ret = avcodec_receive_frame (client->audio.decoder, frame);
+ if (ret < 0)
+ {
+ if (0 && ret != AVERROR (EAGAIN) && ret != AVERROR_EOF)
+ mp4serv_debug (client, "failed to get decoded audio frame: '%s'(%d)",
+ av_err2str (ret), ret);
- frame = av_frame_alloc ();
- frame->pts = packet->pts;
- frame->pkt_dts = frame->pts;
- frame->channel_layout = client->audio.input_channel_layout;
- frame->channels = av_get_channel_layout_nb_channels (frame->channel_layout);
- frame->sample_rate = client->audio.sample_rate;
- frame->format = client->audio.input_sample_fmt;
- frame->nb_samples = pcm_len
- / av_get_bytes_per_sample (frame->format)
- / frame->channels;
-
- avcodec_fill_audio_frame (frame,
- frame->channels,
- frame->format,
- (const uint8_t *) client->audio.buf,
- client->audio.buf_alloc,
- 0);
+ av_frame_free (&frame);
+ break;
+ }
frame->pts = av_rescale_delta (client->audio.input_time_base,
frame->pts,
@@ -1413,7 +1394,6 @@ mp4serv_transcode (Mp4ServClient *client,
av_frame_free (&frame);
}
- while (0);
while (TRUE)
{
--
2.18.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment