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;
|
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 */
|
/* open codec */
|
||||||
if (gst_ffmpeg_avcodec_open (ffmpegaudenc->context, oclass->in_plugin) < 0) {
|
if (gst_ffmpeg_avcodec_open (ffmpegaudenc->context, oclass->in_plugin) < 0) {
|
||||||
if (ffmpegaudenc->context->priv_data)
|
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)),
|
", size %" G_GSIZE_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (inbuf)),
|
||||||
GST_TIME_ARGS (GST_BUFFER_DURATION (inbuf)), gst_buffer_get_size (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);
|
gst_buffer_map (inbuf, &map, GST_MAP_READ);
|
||||||
in_data = map.data;
|
in_data = map.data;
|
||||||
size = map.size;
|
size = map.size;
|
||||||
|
|
|
@ -46,6 +46,9 @@ struct _GstFFMpegAudEnc
|
||||||
/* other settings are copied over straight,
|
/* other settings are copied over straight,
|
||||||
* include a context here, rather than copy-and-past it from avcodec.h */
|
* include a context here, rather than copy-and-past it from avcodec.h */
|
||||||
AVCodecContext config;
|
AVCodecContext config;
|
||||||
|
|
||||||
|
GstAudioChannelPosition ffmpeg_layout[64];
|
||||||
|
gboolean needs_reorder;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _GstFFMpegAudEncClass GstFFMpegAudEncClass;
|
typedef struct _GstFFMpegAudEncClass GstFFMpegAudEncClass;
|
||||||
|
|
|
@ -66,6 +66,32 @@ static const struct
|
||||||
AV_CH_STEREO_RIGHT, GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT}
|
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
|
gboolean
|
||||||
gst_ffmpeg_channel_layout_to_gst (guint64 channel_layout, gint channels,
|
gst_ffmpeg_channel_layout_to_gst (guint64 channel_layout, gint channels,
|
||||||
GstAudioChannelPosition * pos)
|
GstAudioChannelPosition * pos)
|
||||||
|
@ -2325,6 +2351,8 @@ gst_ffmpeg_audioinfo_to_context (GstAudioInfo * info, AVCodecContext * context)
|
||||||
|
|
||||||
context->channels = info->channels;
|
context->channels = info->channels;
|
||||||
context->sample_rate = info->rate;
|
context->sample_rate = info->rate;
|
||||||
|
context->channel_layout =
|
||||||
|
gst_ffmpeg_channel_positions_to_layout (info->position, info->channels);
|
||||||
|
|
||||||
codec = context->codec;
|
codec = context->codec;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue