From fbe1221d70131aa7c3869be60000534cf1dffc70 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 11 Dec 2012 18:07:34 +0000 Subject: [PATCH] avaudenc: Reorder audio channels if necessary and add proper support for channel layouts --- ext/libav/gstavaudenc.c | 18 ++++++++++++++++++ ext/libav/gstavaudenc.h | 3 +++ ext/libav/gstavcodecmap.c | 28 ++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/ext/libav/gstavaudenc.c b/ext/libav/gstavaudenc.c index d3f58cc..c507a8a 100644 --- a/ext/libav/gstavaudenc.c +++ b/ext/libav/gstavaudenc.c @@ -283,6 +283,15 @@ gst_ffmpegaudenc_set_format (GstAudioEncoder * encoder, GstAudioInfo * info) ffmpegaudenc->context->ticks_per_frame = 1; } + if (ffmpegaudenc->context->channel_layout) { + gst_ffmpeg_channel_layout_to_gst (ffmpegaudenc->context->channel_layout, + ffmpegaudenc->context->channels, ffmpegaudenc->ffmpeg_layout); + ffmpegaudenc->needs_reorder = + (memcmp (ffmpegaudenc->ffmpeg_layout, info->position, + sizeof (GstAudioChannelPosition) * + ffmpegaudenc->context->channels) != 0); + } + /* open codec */ if (gst_ffmpeg_avcodec_open (ffmpegaudenc->context, oclass->in_plugin) < 0) { if (ffmpegaudenc->context->priv_data) @@ -540,6 +549,15 @@ gst_ffmpegaudenc_handle_frame (GstAudioEncoder * encoder, GstBuffer * inbuf) ", size %" G_GSIZE_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (inbuf)), GST_TIME_ARGS (GST_BUFFER_DURATION (inbuf)), gst_buffer_get_size (inbuf)); + /* Reorder channels to the GStreamer channel order */ + if (ffmpegaudenc->needs_reorder) { + GstAudioInfo *info = gst_audio_encoder_get_audio_info (encoder); + + inbuf = gst_buffer_make_writable (inbuf); + gst_audio_buffer_reorder_channels (inbuf, info->finfo->format, + info->channels, info->position, ffmpegaudenc->ffmpeg_layout); + } + gst_buffer_map (inbuf, &map, GST_MAP_READ); in_data = map.data; size = map.size; diff --git a/ext/libav/gstavaudenc.h b/ext/libav/gstavaudenc.h index 92527b9..8017ea4 100644 --- a/ext/libav/gstavaudenc.h +++ b/ext/libav/gstavaudenc.h @@ -46,6 +46,9 @@ struct _GstFFMpegAudEnc /* other settings are copied over straight, * include a context here, rather than copy-and-past it from avcodec.h */ AVCodecContext config; + + GstAudioChannelPosition ffmpeg_layout[64]; + gboolean needs_reorder; }; typedef struct _GstFFMpegAudEncClass GstFFMpegAudEncClass; diff --git a/ext/libav/gstavcodecmap.c b/ext/libav/gstavcodecmap.c index b9e6c67..bbd6d60 100644 --- a/ext/libav/gstavcodecmap.c +++ b/ext/libav/gstavcodecmap.c @@ -66,6 +66,32 @@ static const struct AV_CH_STEREO_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT} }; +static guint64 +gst_ffmpeg_channel_positions_to_layout (GstAudioChannelPosition * pos, + gint channels) +{ + gint i, j; + guint64 ret = 0; + gint channels_found = 0; + + if (!pos) + return 0; + + for (i = 0; i < channels; i++) { + for (j = 0; j < G_N_ELEMENTS (_ff_to_gst_layout); j++) { + if (_ff_to_gst_layout[j].gst == pos[i]) { + ret |= _ff_to_gst_layout[i].ff; + channels_found++; + break; + } + } + } + + if (channels_found != channels) + return 0; + return ret; +} + gboolean gst_ffmpeg_channel_layout_to_gst (guint64 channel_layout, gint channels, GstAudioChannelPosition * pos) @@ -2325,6 +2351,8 @@ gst_ffmpeg_audioinfo_to_context (GstAudioInfo * info, AVCodecContext * context) context->channels = info->channels; context->sample_rate = info->rate; + context->channel_layout = + gst_ffmpeg_channel_positions_to_layout (info->position, info->channels); codec = context->codec; -- 2.7.4