summaryrefslogtreecommitdiff
path: root/ext/ffmpeg/gstffmpegcodecmap.c
diff options
context:
space:
mode:
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>2008-10-08 14:20:37 +0000
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>2008-10-08 14:20:37 +0000
commitcc082f9b325ad499cf3bd19d8b04f56de588d4c4 (patch)
tree0cff4a6c2cfebcbbd4c8d14bf8537a415691fb3b /ext/ffmpeg/gstffmpegcodecmap.c
parentd0877c48e4b495de588a5e5d3f8ec9178c6b14aa (diff)
ext/ffmpeg/: Add some more width/height/channels/rate limitations to caps to cater for more automagic negotiation. A...
Original commit message from CVS: * ext/ffmpeg/gstffmpegcodecmap.c: (gst_ff_vid_caps_new), (gst_ff_aud_caps_new), (gst_ffmpeg_codecid_to_caps), (gst_ffmpeg_codectype_to_caps): * ext/ffmpeg/gstffmpegcodecmap.h: * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_negotiate), (gst_ffmpegdec_register): * ext/ffmpeg/gstffmpegenc.c: (gst_ffmpegenc_getcaps), (gst_ffmpegenc_register): Add some more width/height/channels/rate limitations to caps to cater for more automagic negotiation. Addresses #532422.
Diffstat (limited to 'ext/ffmpeg/gstffmpegcodecmap.c')
-rw-r--r--ext/ffmpeg/gstffmpegcodecmap.c156
1 files changed, 125 insertions, 31 deletions
diff --git a/ext/ffmpeg/gstffmpegcodecmap.c b/ext/ffmpeg/gstffmpegcodecmap.c
index 02001e0..2b51f1a 100644
--- a/ext/ffmpeg/gstffmpegcodecmap.c
+++ b/ext/ffmpeg/gstffmpegcodecmap.c
@@ -87,14 +87,28 @@ gst_ff_vid_caps_new (AVCodecContext * context, enum CodecID codec_id,
va_list var_args;
gint i;
- if (context != NULL) {
+ /* fixed, non probing context */
+ if (context != NULL && context->width != -1) {
caps = gst_caps_new_simple (mimetype,
"width", G_TYPE_INT, context->width,
"height", G_TYPE_INT, context->height,
"framerate", GST_TYPE_FRACTION,
context->time_base.den, context->time_base.num, NULL);
- } else {
+ } else if (context) {
+ /* so we are after restricted caps in this case */
switch (codec_id) {
+ case CODEC_ID_H261:
+ {
+ caps = gst_caps_new_simple (mimetype,
+ "width", G_TYPE_INT, 352,
+ "height", G_TYPE_INT, 288,
+ "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
+ gst_caps_append (caps, gst_caps_new_simple (mimetype,
+ "width", G_TYPE_INT, 176,
+ "height", G_TYPE_INT, 144,
+ "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL));
+ break;
+ }
case CODEC_ID_H263:
{
/* 128x96, 176x144, 352x288, 704x576, and 1408x1152. slightly reordered
@@ -131,21 +145,37 @@ gst_ff_vid_caps_new (AVCodecContext * context, enum CodecID codec_id,
"framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
gst_caps_append (caps, temp);
- }
+ }
break;
}
- default:
+ case CODEC_ID_DNXHD:
+ {
caps = gst_caps_new_simple (mimetype,
- "width", GST_TYPE_INT_RANGE, 16, 4096,
- "height", GST_TYPE_INT_RANGE, 16, 4096,
+ "width", G_TYPE_INT, 1920,
+ "height", G_TYPE_INT, 1080,
"framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
+ gst_caps_append (caps, gst_caps_new_simple (mimetype,
+ "width", G_TYPE_INT, 1280,
+ "height", G_TYPE_INT, 720,
+ "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL));
+ break;
+ }
+ default:
break;
}
}
+ /* no fixed caps or special restrictions applied;
+ * default unfixed setting */
+ if (!caps)
+ caps = gst_caps_new_simple (mimetype,
+ "width", GST_TYPE_INT_RANGE, 16, 4096,
+ "height", GST_TYPE_INT_RANGE, 16, 4096,
+ "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
+
for (i = 0; i < gst_caps_get_size (caps); i++) {
- structure = gst_caps_get_structure (caps, i);
va_start (var_args, fieldname);
+ structure = gst_caps_get_structure (caps, i);
gst_structure_set_valist (structure, fieldname, var_args);
va_end (var_args);
}
@@ -162,36 +192,94 @@ gst_ff_aud_caps_new (AVCodecContext * context, enum CodecID codec_id,
{
GstCaps *caps = NULL;
GstStructure *structure = NULL;
+ gint i;
va_list var_args;
- if (context != NULL) {
+ /* fixed, non-probing context */
+ if (context != NULL && context->channels != -1) {
caps = gst_caps_new_simple (mimetype,
"rate", G_TYPE_INT, context->sample_rate,
"channels", G_TYPE_INT, context->channels, NULL);
} else {
- gint maxchannels;
- /* Until decoders/encoders expose the maximum number of channels
- * they support, we whitelist them here. */
- switch (codec_id) {
- case CODEC_ID_AC3:
- case CODEC_ID_AAC:
- case CODEC_ID_DTS:
- maxchannels = 6;
- break;
- default:
- maxchannels = 2;
- }
+ gint maxchannels = 2;
+ const gint *rates = NULL;
+ gint n_rates = 0;
- caps = gst_caps_new_simple (mimetype,
- "rate", GST_TYPE_INT_RANGE, 8000, 96000,
- "channels", GST_TYPE_INT_RANGE, 1, maxchannels, NULL);
+ if (context)
+ /* so we must be after restricted caps in this particular case */
+ switch (codec_id) {
+ case CODEC_ID_MP2:
+ {
+ const static gint l_rates[] =
+ { 48000, 44100, 32000, 24000, 22050, 16000 };
+ n_rates = G_N_ELEMENTS (l_rates);
+ rates = l_rates;
+ break;
+ }
+ case CODEC_ID_AC3:
+ {
+ const static gint l_rates[] = { 48000, 44100, 32000 };
+ n_rates = G_N_ELEMENTS (l_rates);
+ rates = l_rates;
+ maxchannels = 6;
+ break;
+ }
+ case CODEC_ID_ADPCM_SWF:
+ {
+ const static gint l_rates[] = { 11025, 22050, 44100 };
+ n_rates = G_N_ELEMENTS (l_rates);
+ rates = l_rates;
+ break;
+ }
+ case CODEC_ID_ROQ_DPCM:
+ {
+ const static gint l_rates[] = { 22050 };
+ n_rates = G_N_ELEMENTS (l_rates);
+ rates = l_rates;
+ break;
+ }
+ case CODEC_ID_ADPCM_G726:
+ maxchannels = 1;
+ break;
+ case CODEC_ID_AAC:
+ case CODEC_ID_DTS:
+ /* Until decoders/encoders expose the maximum number of channels
+ * they support, we whitelist them here. */
+ maxchannels = 6;
+ break;
+ default:
+ break;
+ }
+ if (maxchannels == 1)
+ caps = gst_caps_new_simple (mimetype,
+ "channels", G_TYPE_INT, maxchannels, NULL);
+ else
+ caps = gst_caps_new_simple (mimetype,
+ "channels", GST_TYPE_INT_RANGE, 1, maxchannels, NULL);
+ if (n_rates) {
+ GValue list = { 0, };
+ GstStructure *structure;
+
+ g_value_init (&list, GST_TYPE_LIST);
+ for (i = 0; i < n_rates; i++) {
+ GValue v = { 0, };
+
+ g_value_init (&v, G_TYPE_INT);
+ g_value_set_int (&v, rates[i]);
+ gst_value_list_append_value (&list, &v);
+ g_value_unset (&v);
+ }
+ structure = gst_caps_get_structure (caps, 0);
+ gst_structure_set_value (structure, "rate", &list);
+ g_value_unset (&list);
+ } else
+ gst_caps_set_simple (caps, "rate", GST_TYPE_INT_RANGE, 8000, 96000, NULL);
}
- structure = gst_caps_get_structure (caps, 0);
-
- if (structure) {
+ for (i = 0; i < gst_caps_get_size (caps); i++) {
va_start (var_args, fieldname);
+ structure = gst_caps_get_structure (caps, i);
gst_structure_set_valist (structure, fieldname, var_args);
va_end (var_args);
}
@@ -428,7 +516,8 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
break;
case CODEC_ID_RAWVIDEO:
- caps = gst_ffmpeg_codectype_to_caps (CODEC_TYPE_VIDEO, context, codec_id);
+ caps = gst_ffmpeg_codectype_to_caps (CODEC_TYPE_VIDEO, context, codec_id,
+ encode);
break;
case CODEC_ID_MSMPEG4V1:
@@ -1366,7 +1455,7 @@ gst_ffmpeg_smpfmt_to_caps (enum SampleFormat sample_fmt,
GstCaps *
gst_ffmpeg_codectype_to_caps (enum CodecType codec_type,
- AVCodecContext * context, enum CodecID codec_id)
+ AVCodecContext * context, enum CodecID codec_id, gboolean encode)
{
GstCaps *caps;
@@ -1374,14 +1463,17 @@ gst_ffmpeg_codectype_to_caps (enum CodecType codec_type,
case CODEC_TYPE_VIDEO:
if (context) {
caps = gst_ffmpeg_pixfmt_to_caps (context->pix_fmt,
- context->width == -1 ? NULL : context, codec_id);
+ 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++) {
- temp = gst_ffmpeg_pixfmt_to_caps (i, NULL, codec_id);
+ 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);
}
@@ -1396,10 +1488,12 @@ gst_ffmpeg_codectype_to_caps (enum CodecType codec_type,
} else {
GstCaps *temp;
enum SampleFormat i;
+ AVCodecContext ctx = { 0, };
+ ctx.channels = -1;
caps = gst_caps_new_empty ();
for (i = 0; i <= SAMPLE_FMT_S16; i++) {
- temp = gst_ffmpeg_smpfmt_to_caps (i, NULL, codec_id);
+ temp = gst_ffmpeg_smpfmt_to_caps (i, encode ? &ctx : NULL, codec_id);
if (temp != NULL) {
gst_caps_append (caps, temp);
}