mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +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;
|
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
|
/* Convert a FFMPEG codec Type and optional AVCodecContext
|
||||||
* to a GstCaps. If the context is ommitted, no fixed values
|
* to a GstCaps. If the context is ommitted, no fixed values
|
||||||
* for video/audio size will be included in the GstCaps
|
* 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) {
|
switch (codec_type) {
|
||||||
case CODEC_TYPE_VIDEO:
|
case CODEC_TYPE_VIDEO:
|
||||||
if (context) {
|
caps =
|
||||||
caps = gst_ffmpeg_pixfmt_to_caps (context->pix_fmt, context, codec_id);
|
gst_ffmpeg_codectype_to_video_caps (context, codec_id, encode, NULL);
|
||||||
} 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CODEC_TYPE_AUDIO:
|
case CODEC_TYPE_AUDIO:
|
||||||
if (context) {
|
caps =
|
||||||
caps =
|
gst_ffmpeg_codectype_to_audio_caps (context, codec_id, encode, NULL);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* .. */
|
|
||||||
caps = NULL;
|
caps = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,16 @@ gst_ffmpeg_codectype_to_caps (enum CodecType codec_type,
|
||||||
AVCodecContext *context,
|
AVCodecContext *context,
|
||||||
enum CodecID codec_id,
|
enum CodecID codec_id,
|
||||||
gboolean encode);
|
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
|
* 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) {
|
if (in_plugin->type == CODEC_TYPE_VIDEO) {
|
||||||
srccaps = gst_caps_from_string ("video/x-raw-rgb; video/x-raw-yuv");
|
srccaps = gst_caps_from_string ("video/x-raw-rgb; video/x-raw-yuv");
|
||||||
} else {
|
} else {
|
||||||
srccaps = gst_ffmpeg_codectype_to_caps (in_plugin->type, NULL,
|
srccaps = gst_ffmpeg_codectype_to_audio_caps (NULL,
|
||||||
in_plugin->id, FALSE);
|
in_plugin->id, FALSE, in_plugin);
|
||||||
}
|
}
|
||||||
if (!srccaps) {
|
if (!srccaps) {
|
||||||
GST_WARNING ("Couldn't get source caps for decoder %s", in_plugin->name);
|
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
|
sinkcaps = gst_caps_from_string
|
||||||
("video/x-raw-rgb; video/x-raw-yuv; video/x-raw-gray");
|
("video/x-raw-rgb; video/x-raw-yuv; video/x-raw-gray");
|
||||||
} else {
|
} else {
|
||||||
sinkcaps = gst_ffmpeg_codectype_to_caps (in_plugin->type, NULL,
|
sinkcaps = gst_ffmpeg_codectype_to_audio_caps (NULL,
|
||||||
in_plugin->id, TRUE);
|
in_plugin->id, TRUE, in_plugin);
|
||||||
}
|
}
|
||||||
if (!sinkcaps) {
|
if (!sinkcaps) {
|
||||||
GST_WARNING ("Couldn't get sink caps for encoder %s", in_plugin->name);
|
GST_WARNING ("Couldn't get sink caps for encoder %s", in_plugin->name);
|
||||||
|
|
Loading…
Reference in a new issue