mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-28 20:05:38 +00:00
Only use valid SampleFormat for audio encoders/decoders.
For a given AVCodec, when the sample_fmts field is non-NULL, that means that that codec can only handle a specific set of SampleFormat. With this patch, we now look for its presence and create the proper pad template caps. Fixes #569441
This commit is contained in:
parent
b09bdde7d2
commit
9fc91546ea
4 changed files with 87 additions and 41 deletions
|
@ -1624,6 +1624,75 @@ gst_ffmpeg_smpfmt_to_caps (enum SampleFormat sample_fmt,
|
|||
return caps;
|
||||
}
|
||||
|
||||
GstCaps *
|
||||
gst_ffmpeg_codectype_to_audio_caps (AVCodecContext * context,
|
||||
enum CodecID codec_id, gboolean encode, AVCodec * codec)
|
||||
{
|
||||
GstCaps *caps = NULL;
|
||||
|
||||
GST_DEBUG ("context:%p, codec_id:%d, encode:%d, codec:%p",
|
||||
context, codec_id, encode, codec);
|
||||
if (codec)
|
||||
GST_DEBUG ("sample_fmts:%p, samplerates:%p",
|
||||
codec->sample_fmts, codec->supported_samplerates);
|
||||
|
||||
if (context) {
|
||||
/* Specific codec context */
|
||||
caps = gst_ffmpeg_smpfmt_to_caps (context->sample_fmt, context, codec_id);
|
||||
} else if (codec && codec->sample_fmts) {
|
||||
GstCaps *temp;
|
||||
int i;
|
||||
|
||||
caps = gst_caps_new_empty ();
|
||||
for (i = 0; codec->sample_fmts[i] != -1; i++) {
|
||||
temp =
|
||||
gst_ffmpeg_smpfmt_to_caps (codec->sample_fmts[0], context, codec_id);
|
||||
if (temp != NULL)
|
||||
gst_caps_append (caps, temp);
|
||||
}
|
||||
} else {
|
||||
GstCaps *temp;
|
||||
enum SampleFormat i;
|
||||
AVCodecContext ctx = { 0, };
|
||||
|
||||
ctx.channels = -1;
|
||||
caps = gst_caps_new_empty ();
|
||||
for (i = 0; i <= SAMPLE_FMT_DBL; i++) {
|
||||
temp = gst_ffmpeg_smpfmt_to_caps (i, encode ? &ctx : NULL, codec_id);
|
||||
if (temp != NULL) {
|
||||
gst_caps_append (caps, temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
return caps;
|
||||
}
|
||||
|
||||
GstCaps *
|
||||
gst_ffmpeg_codectype_to_video_caps (AVCodecContext * context,
|
||||
enum CodecID codec_id, gboolean encode, AVCodec * codec)
|
||||
{
|
||||
GstCaps *caps;
|
||||
|
||||
if (context) {
|
||||
caps = gst_ffmpeg_pixfmt_to_caps (context->pix_fmt, context, codec_id);
|
||||
} else {
|
||||
GstCaps *temp;
|
||||
enum PixelFormat i;
|
||||
AVCodecContext ctx = { 0, };
|
||||
|
||||
caps = gst_caps_new_empty ();
|
||||
for (i = 0; i < PIX_FMT_NB; i++) {
|
||||
ctx.width = -1;
|
||||
ctx.pix_fmt = i;
|
||||
temp = gst_ffmpeg_pixfmt_to_caps (i, encode ? &ctx : NULL, codec_id);
|
||||
if (temp != NULL) {
|
||||
gst_caps_append (caps, temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
return caps;
|
||||
}
|
||||
|
||||
/* Convert a FFMPEG codec Type and optional AVCodecContext
|
||||
* to a GstCaps. If the context is ommitted, no fixed values
|
||||
* for video/audio size will be included in the GstCaps
|
||||
|
@ -1639,47 +1708,14 @@ gst_ffmpeg_codectype_to_caps (enum CodecType codec_type,
|
|||
|
||||
switch (codec_type) {
|
||||
case CODEC_TYPE_VIDEO:
|
||||
if (context) {
|
||||
caps = gst_ffmpeg_pixfmt_to_caps (context->pix_fmt, context, codec_id);
|
||||
} else {
|
||||
GstCaps *temp;
|
||||
enum PixelFormat i;
|
||||
AVCodecContext ctx = { 0, };
|
||||
|
||||
caps = gst_caps_new_empty ();
|
||||
for (i = 0; i < PIX_FMT_NB; i++) {
|
||||
ctx.width = -1;
|
||||
ctx.pix_fmt = i;
|
||||
temp = gst_ffmpeg_pixfmt_to_caps (i, encode ? &ctx : NULL, codec_id);
|
||||
if (temp != NULL) {
|
||||
gst_caps_append (caps, temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
caps =
|
||||
gst_ffmpeg_codectype_to_video_caps (context, codec_id, encode, NULL);
|
||||
break;
|
||||
|
||||
case CODEC_TYPE_AUDIO:
|
||||
if (context) {
|
||||
caps =
|
||||
gst_ffmpeg_smpfmt_to_caps (context->sample_fmt, context, codec_id);
|
||||
} else {
|
||||
GstCaps *temp;
|
||||
enum SampleFormat i;
|
||||
AVCodecContext ctx = { 0, };
|
||||
|
||||
ctx.channels = -1;
|
||||
caps = gst_caps_new_empty ();
|
||||
for (i = 0; i <= SAMPLE_FMT_DBL; i++) {
|
||||
temp = gst_ffmpeg_smpfmt_to_caps (i, encode ? &ctx : NULL, codec_id);
|
||||
if (temp != NULL) {
|
||||
gst_caps_append (caps, temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
caps =
|
||||
gst_ffmpeg_codectype_to_audio_caps (context, codec_id, encode, NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* .. */
|
||||
caps = NULL;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -49,6 +49,16 @@ gst_ffmpeg_codectype_to_caps (enum CodecType codec_type,
|
|||
AVCodecContext *context,
|
||||
enum CodecID codec_id,
|
||||
gboolean encode);
|
||||
GstCaps *
|
||||
gst_ffmpeg_codectype_to_audio_caps (AVCodecContext *context,
|
||||
enum CodecID codec_id,
|
||||
gboolean encode,
|
||||
AVCodec *codec);
|
||||
GstCaps *
|
||||
gst_ffmpeg_codectype_to_video_caps (AVCodecContext *context,
|
||||
enum CodecID codec_id,
|
||||
gboolean encode,
|
||||
AVCodec *codec);
|
||||
|
||||
/*
|
||||
* caps_to_codecid () transforms a GstCaps that belongs to
|
||||
|
|
|
@ -2563,8 +2563,8 @@ gst_ffmpegdec_register (GstPlugin * plugin)
|
|||
if (in_plugin->type == CODEC_TYPE_VIDEO) {
|
||||
srccaps = gst_caps_from_string ("video/x-raw-rgb; video/x-raw-yuv");
|
||||
} else {
|
||||
srccaps = gst_ffmpeg_codectype_to_caps (in_plugin->type, NULL,
|
||||
in_plugin->id, FALSE);
|
||||
srccaps = gst_ffmpeg_codectype_to_audio_caps (NULL,
|
||||
in_plugin->id, FALSE, in_plugin);
|
||||
}
|
||||
if (!srccaps) {
|
||||
GST_WARNING ("Couldn't get source caps for decoder %s", in_plugin->name);
|
||||
|
|
|
@ -1029,8 +1029,8 @@ gst_ffmpegenc_register (GstPlugin * plugin)
|
|||
sinkcaps = gst_caps_from_string
|
||||
("video/x-raw-rgb; video/x-raw-yuv; video/x-raw-gray");
|
||||
} else {
|
||||
sinkcaps = gst_ffmpeg_codectype_to_caps (in_plugin->type, NULL,
|
||||
in_plugin->id, TRUE);
|
||||
sinkcaps = gst_ffmpeg_codectype_to_audio_caps (NULL,
|
||||
in_plugin->id, TRUE, in_plugin);
|
||||
}
|
||||
if (!sinkcaps) {
|
||||
GST_WARNING ("Couldn't get sink caps for encoder %s", in_plugin->name);
|
||||
|
|
Loading…
Reference in a new issue