mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-10 17:35:59 +00:00
avaudenc: Reorder audio channels if necessary and add proper support for channel layouts
This commit is contained in:
parent
64a2a8bdae
commit
fbe1221d70
3 changed files with 49 additions and 0 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue