Created
August 23, 2018 05:05
-
-
Save moonpfe/b380e6f82226190ab367570c18125fa8 to your computer and use it in GitHub Desktop.
FFmpeg ADPCM 디코더를 사용하여 오디오 디코딩
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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