mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-30 12:10:37 +00:00
avcodecmap: Take channel layout constraints into account if possible
This commit is contained in:
parent
b9d0c7110f
commit
64a2a8bdae
3 changed files with 57 additions and 27 deletions
|
@ -360,7 +360,8 @@ gst_ffmpegauddec_negotiate (GstFFMpegAudDec * ffmpegdec, gboolean force)
|
||||||
ffmpegdec->info.finfo->depth,
|
ffmpegdec->info.finfo->depth,
|
||||||
ffmpegdec->context->sample_rate, ffmpegdec->context->channels, depth);
|
ffmpegdec->context->sample_rate, ffmpegdec->context->channels, depth);
|
||||||
|
|
||||||
gst_ffmpeg_channel_layout_to_gst (ffmpegdec->context, pos);
|
gst_ffmpeg_channel_layout_to_gst (ffmpegdec->context->channel_layout,
|
||||||
|
ffmpegdec->context->channels, pos);
|
||||||
memcpy (ffmpegdec->ffmpeg_layout, pos,
|
memcpy (ffmpegdec->ffmpeg_layout, pos,
|
||||||
sizeof (GstAudioChannelPosition) * ffmpegdec->context->channels);
|
sizeof (GstAudioChannelPosition) * ffmpegdec->context->channels);
|
||||||
|
|
||||||
|
|
|
@ -67,11 +67,10 @@ static const struct
|
||||||
};
|
};
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_ffmpeg_channel_layout_to_gst (AVCodecContext * context,
|
gst_ffmpeg_channel_layout_to_gst (guint64 channel_layout, gint channels,
|
||||||
GstAudioChannelPosition * pos)
|
GstAudioChannelPosition * pos)
|
||||||
{
|
{
|
||||||
guint nchannels = 0, channels = context->channels;
|
guint nchannels = 0;
|
||||||
guint64 channel_layout = context->channel_layout;
|
|
||||||
gboolean none_layout = FALSE;
|
gboolean none_layout = FALSE;
|
||||||
|
|
||||||
if (channel_layout == 0) {
|
if (channel_layout == 0) {
|
||||||
|
@ -279,6 +278,20 @@ gst_ff_vid_caps_new (AVCodecContext * context, enum CodecID codec_id,
|
||||||
return caps;
|
return caps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gint
|
||||||
|
get_nbits_set (guint64 n)
|
||||||
|
{
|
||||||
|
gint i, x;
|
||||||
|
|
||||||
|
x = 0;
|
||||||
|
for (i = 0; i < 64; i++) {
|
||||||
|
if ((n & (G_GUINT64_CONSTANT (1) << i)))
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
/* same for audio - now with channels/sample rate
|
/* same for audio - now with channels/sample rate
|
||||||
*/
|
*/
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
|
@ -287,7 +300,6 @@ gst_ff_aud_caps_new (AVCodecContext * context, AVCodec * codec,
|
||||||
const char *fieldname, ...)
|
const char *fieldname, ...)
|
||||||
{
|
{
|
||||||
GstCaps *caps = NULL;
|
GstCaps *caps = NULL;
|
||||||
GstStructure *structure = NULL;
|
|
||||||
gint i;
|
gint i;
|
||||||
va_list var_args;
|
va_list var_args;
|
||||||
|
|
||||||
|
@ -299,7 +311,8 @@ gst_ff_aud_caps_new (AVCodecContext * context, AVCodec * codec,
|
||||||
"rate", G_TYPE_INT, context->sample_rate,
|
"rate", G_TYPE_INT, context->sample_rate,
|
||||||
"channels", G_TYPE_INT, context->channels, NULL);
|
"channels", G_TYPE_INT, context->channels, NULL);
|
||||||
|
|
||||||
if (gst_ffmpeg_channel_layout_to_gst (context, pos)) {
|
if (gst_ffmpeg_channel_layout_to_gst (context->channel_layout,
|
||||||
|
context->channels, pos)) {
|
||||||
guint64 mask;
|
guint64 mask;
|
||||||
|
|
||||||
if (gst_audio_channel_positions_to_mask (pos, context->channels, FALSE,
|
if (gst_audio_channel_positions_to_mask (pos, context->channels, FALSE,
|
||||||
|
@ -387,10 +400,6 @@ gst_ff_aud_caps_new (AVCodecContext * context, AVCodec * codec,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: handle context->channel_layouts here to set
|
|
||||||
* the list of channel layouts supported by the encoder.
|
|
||||||
* Unfortunately no encoder uses this yet....
|
|
||||||
*/
|
|
||||||
/* regardless of encode/decode, open up channels if applicable */
|
/* regardless of encode/decode, open up channels if applicable */
|
||||||
/* Until decoders/encoders expose the maximum number of channels
|
/* Until decoders/encoders expose the maximum number of channels
|
||||||
* they support, we whitelist them here. */
|
* they support, we whitelist them here. */
|
||||||
|
@ -403,15 +412,40 @@ gst_ff_aud_caps_new (AVCodecContext * context, AVCodec * codec,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (codec && codec->channel_layouts) {
|
||||||
|
const uint64_t *layouts = codec->channel_layouts;
|
||||||
|
GstAudioChannelPosition pos[64];
|
||||||
|
|
||||||
|
caps = gst_caps_new_empty ();
|
||||||
|
while (*layouts) {
|
||||||
|
gint nbits_set = get_nbits_set (*layouts);
|
||||||
|
|
||||||
|
if (gst_ffmpeg_channel_layout_to_gst (*layouts, nbits_set, pos)) {
|
||||||
|
guint64 mask;
|
||||||
|
|
||||||
|
if (gst_audio_channel_positions_to_mask (pos, nbits_set, FALSE,
|
||||||
|
&mask)) {
|
||||||
|
GstCaps *tmp =
|
||||||
|
gst_caps_new_simple (mimetype, "channel-mask", GST_TYPE_BITMASK,
|
||||||
|
mask,
|
||||||
|
"channels", G_TYPE_INT, nbits_set, NULL);
|
||||||
|
|
||||||
|
gst_caps_append (caps, tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
layouts++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (maxchannels == 1)
|
if (maxchannels == 1)
|
||||||
caps = gst_caps_new_simple (mimetype,
|
caps = gst_caps_new_simple (mimetype,
|
||||||
"channels", G_TYPE_INT, maxchannels, NULL);
|
"channels", G_TYPE_INT, maxchannels, NULL);
|
||||||
else
|
else
|
||||||
caps = gst_caps_new_simple (mimetype,
|
caps = gst_caps_new_simple (mimetype,
|
||||||
"channels", GST_TYPE_INT_RANGE, 1, maxchannels, NULL);
|
"channels", GST_TYPE_INT_RANGE, 1, maxchannels, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if (n_rates) {
|
if (n_rates) {
|
||||||
GValue list = { 0, };
|
GValue list = { 0, };
|
||||||
GstStructure *structure;
|
|
||||||
|
|
||||||
g_value_init (&list, GST_TYPE_LIST);
|
g_value_init (&list, GST_TYPE_LIST);
|
||||||
for (i = 0; i < n_rates; i++) {
|
for (i = 0; i < n_rates; i++) {
|
||||||
|
@ -422,8 +456,7 @@ gst_ff_aud_caps_new (AVCodecContext * context, AVCodec * codec,
|
||||||
gst_value_list_append_value (&list, &v);
|
gst_value_list_append_value (&list, &v);
|
||||||
g_value_unset (&v);
|
g_value_unset (&v);
|
||||||
}
|
}
|
||||||
structure = gst_caps_get_structure (caps, 0);
|
gst_caps_set_value (caps, "rate", &list);
|
||||||
gst_structure_set_value (structure, "rate", &list);
|
|
||||||
g_value_unset (&list);
|
g_value_unset (&list);
|
||||||
} else if (codec && codec->supported_samplerates
|
} else if (codec && codec->supported_samplerates
|
||||||
&& codec->supported_samplerates[0]) {
|
&& codec->supported_samplerates[0]) {
|
||||||
|
@ -455,12 +488,9 @@ gst_ff_aud_caps_new (AVCodecContext * context, AVCodec * codec,
|
||||||
caps = gst_caps_new_empty_simple (mimetype);
|
caps = gst_caps_new_empty_simple (mimetype);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < gst_caps_get_size (caps); i++) {
|
|
||||||
va_start (var_args, fieldname);
|
va_start (var_args, fieldname);
|
||||||
structure = gst_caps_get_structure (caps, i);
|
gst_caps_set_simple_valist (caps, fieldname, var_args);
|
||||||
gst_structure_set_valist (structure, fieldname, var_args);
|
|
||||||
va_end (var_args);
|
va_end (var_args);
|
||||||
}
|
|
||||||
|
|
||||||
return caps;
|
return caps;
|
||||||
}
|
}
|
||||||
|
@ -1922,7 +1952,6 @@ gst_ffmpeg_codectype_to_audio_caps (AVCodecContext * context,
|
||||||
} else {
|
} else {
|
||||||
caps = gst_ff_aud_caps_new (context, codec, codec_id, TRUE, "audio/x-raw",
|
caps = gst_ff_aud_caps_new (context, codec, codec_id, TRUE, "audio/x-raw",
|
||||||
"layout", G_TYPE_STRING, "interleaved", NULL);
|
"layout", G_TYPE_STRING, "interleaved", NULL);
|
||||||
|
|
||||||
gst_ffmpeg_audio_set_sample_fmts (caps, codec ? codec->sample_fmts : NULL);
|
gst_ffmpeg_audio_set_sample_fmts (caps, codec ? codec->sample_fmts : NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -137,7 +137,7 @@ gst_ffmpeg_formatid_get_codecids (const gchar *format_name,
|
||||||
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_ffmpeg_channel_layout_to_gst (AVCodecContext * context,
|
gst_ffmpeg_channel_layout_to_gst (guint64 channel_layout, gint channels,
|
||||||
GstAudioChannelPosition * pos);
|
GstAudioChannelPosition * pos);
|
||||||
|
|
||||||
#endif /* __GST_FFMPEG_CODECMAP_H__ */
|
#endif /* __GST_FFMPEG_CODECMAP_H__ */
|
||||||
|
|
Loading…
Reference in a new issue