avcodecmap: Take generic samplerate limitations into account

This commit is contained in:
Sebastian Dröge 2012-12-11 16:54:09 +00:00
parent 90e1c0c21d
commit b9d0c7110f

View file

@ -282,8 +282,9 @@ gst_ff_vid_caps_new (AVCodecContext * context, enum CodecID codec_id,
/* same for audio - now with channels/sample rate
*/
static GstCaps *
gst_ff_aud_caps_new (AVCodecContext * context, enum CodecID codec_id,
gboolean encode, const char *mimetype, const char *fieldname, ...)
gst_ff_aud_caps_new (AVCodecContext * context, AVCodec * codec,
enum CodecID codec_id, gboolean encode, const char *mimetype,
const char *fieldname, ...)
{
GstCaps *caps = NULL;
GstStructure *structure = NULL;
@ -424,8 +425,32 @@ gst_ff_aud_caps_new (AVCodecContext * context, enum CodecID codec_id,
structure = gst_caps_get_structure (caps, 0);
gst_structure_set_value (structure, "rate", &list);
g_value_unset (&list);
} else
} else if (codec && codec->supported_samplerates
&& codec->supported_samplerates[0]) {
GValue va = { 0, };
GValue v = { 0, };
if (!codec->supported_samplerates[1]) {
gst_caps_set_simple (caps, "rate", G_TYPE_INT,
codec->supported_samplerates[0], NULL);
} else {
const int *rates = codec->supported_samplerates;
g_value_init (&va, GST_TYPE_LIST);
g_value_init (&v, G_TYPE_INT);
while (*rates) {
g_value_set_int (&v, *rates);
gst_value_list_append_value (&va, &v);
rates++;
}
gst_caps_set_value (caps, "rate", &va);
g_value_unset (&va);
g_value_unset (&v);
}
} else {
gst_caps_set_simple (caps, "rate", GST_TYPE_INT_RANGE, 4000, 96000, NULL);
}
} else {
caps = gst_caps_new_empty_simple (mimetype);
}
@ -573,20 +598,21 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
case CODEC_ID_MP1:
/* FIXME: bitrate */
caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/mpeg",
caps = gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/mpeg",
"mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 1, NULL);
break;
case CODEC_ID_MP2:
/* FIXME: bitrate */
caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/mpeg",
caps = gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/mpeg",
"mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 2, NULL);
break;
case CODEC_ID_MP3:
if (encode) {
/* FIXME: bitrate */
caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/mpeg",
caps =
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/mpeg",
"mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, 3, NULL);
} else {
/* Decodes MPEG-1 layer 1/2/3. Samplerate, channels et al are
@ -599,14 +625,14 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
case CODEC_ID_MUSEPACK7:
caps =
gst_ff_aud_caps_new (context, codec_id, encode,
gst_ff_aud_caps_new (context, NULL, codec_id, encode,
"audio/x-ffmpeg-parsed-musepack", "streamversion", G_TYPE_INT, 7,
NULL);
break;
case CODEC_ID_MUSEPACK8:
caps =
gst_ff_aud_caps_new (context, codec_id, encode,
gst_ff_aud_caps_new (context, NULL, codec_id, encode,
"audio/x-ffmpeg-parsed-musepack", "streamversion", G_TYPE_INT, 8,
NULL);
break;
@ -614,41 +640,44 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
case CODEC_ID_AC3:
/* FIXME: bitrate */
caps =
gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-ac3", NULL);
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-ac3",
NULL);
break;
case CODEC_ID_EAC3:
/* FIXME: bitrate */
caps =
gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-eac3", NULL);
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-eac3",
NULL);
break;
case CODEC_ID_TRUEHD:
caps =
gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-true-hd",
NULL);
gst_ff_aud_caps_new (context, NULL, codec_id, encode,
"audio/x-true-hd", NULL);
break;
case CODEC_ID_ATRAC1:
caps =
gst_ff_aud_caps_new (context, codec_id, encode,
gst_ff_aud_caps_new (context, NULL, codec_id, encode,
"audio/x-vnd.sony.atrac1", NULL);
break;
case CODEC_ID_ATRAC3:
caps =
gst_ff_aud_caps_new (context, codec_id, encode,
gst_ff_aud_caps_new (context, NULL, codec_id, encode,
"audio/x-vnd.sony.atrac3", NULL);
break;
case CODEC_ID_DTS:
caps =
gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-dts", NULL);
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-dts",
NULL);
break;
case CODEC_ID_APE:
caps =
gst_ff_aud_caps_new (context, codec_id, encode,
gst_ff_aud_caps_new (context, NULL, codec_id, encode,
"audio/x-ffmpeg-parsed-ape", NULL);
if (context) {
gst_caps_set_simple (caps,
@ -658,12 +687,14 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
case CODEC_ID_MLP:
caps =
gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-mlp", NULL);
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-mlp",
NULL);
break;
case CODEC_ID_IMC:
caps =
gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-imc", NULL);
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-imc",
NULL);
break;
/* MJPEG is normal JPEG, Motion-JPEG and Quicktime MJPEG-A. MJPEGB
@ -776,7 +807,8 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
case CODEC_ID_DVAUDIO:
caps =
gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-dv", NULL);
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-dv",
NULL);
break;
case CODEC_ID_DVVIDEO:
@ -826,21 +858,24 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
gint version = (codec_id == CODEC_ID_WMAV1) ? 1 : 2;
if (context) {
caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-wma",
"wmaversion", G_TYPE_INT, version,
"block_align", G_TYPE_INT, context->block_align,
"bitrate", G_TYPE_INT, context->bit_rate, NULL);
caps =
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-wma",
"wmaversion", G_TYPE_INT, version, "block_align", G_TYPE_INT,
context->block_align, "bitrate", G_TYPE_INT, context->bit_rate,
NULL);
} else {
caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-wma",
"wmaversion", G_TYPE_INT, version,
"block_align", GST_TYPE_INT_RANGE, 0, G_MAXINT,
"bitrate", GST_TYPE_INT_RANGE, 0, G_MAXINT, NULL);
caps =
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-wma",
"wmaversion", G_TYPE_INT, version, "block_align",
GST_TYPE_INT_RANGE, 0, G_MAXINT, "bitrate", GST_TYPE_INT_RANGE, 0,
G_MAXINT, NULL);
}
}
break;
case CODEC_ID_WMAPRO:
{
caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-wma",
caps =
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-wma",
"wmaversion", G_TYPE_INT, 3, NULL);
break;
}
@ -848,7 +883,8 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
case CODEC_ID_WMAVOICE:
{
caps =
gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-wms", NULL);
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-wms",
NULL);
break;
}
@ -857,7 +893,8 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
{
gint version = (codec_id == CODEC_ID_MACE3) ? 3 : 6;
caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-mace",
caps =
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-mace",
"maceversion", G_TYPE_INT, version, NULL);
}
break;
@ -951,7 +988,8 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
case CODEC_ID_AAC:
{
caps =
gst_ff_aud_caps_new (context, codec_id, encode, "audio/mpeg", NULL);
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/mpeg",
NULL);
if (!encode) {
GValue arr = { 0, };
@ -993,7 +1031,7 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
break;
}
case CODEC_ID_AAC_LATM: /* LATM/LOAS AAC syntax */
caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/mpeg",
caps = gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/mpeg",
"mpegversion", G_TYPE_INT, 4, "stream-format", G_TYPE_STRING, "loas",
NULL);
break;
@ -1098,7 +1136,8 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
break;
case CODEC_ID_QDM2:
caps =
gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-qdm2", NULL);
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-qdm2",
NULL);
break;
case CODEC_ID_MSZH:
@ -1239,13 +1278,14 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
case CODEC_ID_TRUESPEECH:
caps =
gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-truespeech",
NULL);
gst_ff_aud_caps_new (context, NULL, codec_id, encode,
"audio/x-truespeech", NULL);
break;
case CODEC_ID_QCELP:
caps =
gst_ff_aud_caps_new (context, codec_id, encode, "audio/qcelp", NULL);
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/qcelp",
NULL);
break;
case CODEC_ID_AMV:
@ -1341,7 +1381,8 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
break;
}
caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-raw",
caps =
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-raw",
"format", G_TYPE_STRING, gst_audio_format_to_string (format),
"layout", G_TYPE_STRING, "interleaved", NULL);
}
@ -1349,18 +1390,20 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
case CODEC_ID_PCM_MULAW:
caps =
gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-mulaw",
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-mulaw",
NULL);
break;
case CODEC_ID_PCM_ALAW:
caps =
gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-alaw", NULL);
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-alaw",
NULL);
break;
case CODEC_ID_ADPCM_G722:
caps =
gst_ff_aud_caps_new (context, codec_id, encode, "audio/G722", NULL);
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/G722",
NULL);
if (context)
gst_caps_set_simple (caps,
"block_align", G_TYPE_INT, context->block_align,
@ -1370,7 +1413,8 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
case CODEC_ID_ADPCM_G726:
{
/* the G726 decoder can also handle G721 */
caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-adpcm",
caps =
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-adpcm",
"layout", G_TYPE_STRING, "g726", NULL);
if (context)
gst_caps_set_simple (caps,
@ -1503,7 +1547,8 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
/* FIXME: someone please check whether we need additional properties
* in this caps definition. */
caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-adpcm",
caps =
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-adpcm",
"layout", G_TYPE_STRING, layout, NULL);
if (context)
gst_caps_set_simple (caps,
@ -1513,34 +1558,39 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
break;
case CODEC_ID_AMR_NB:
caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/AMR", NULL);
caps =
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/AMR",
NULL);
break;
case CODEC_ID_AMR_WB:
caps =
gst_ff_aud_caps_new (context, codec_id, encode, "audio/AMR-WB", NULL);
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/AMR-WB",
NULL);
break;
case CODEC_ID_GSM:
caps =
gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-gsm", NULL);
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-gsm",
NULL);
break;
case CODEC_ID_GSM_MS:
caps =
gst_ff_aud_caps_new (context, codec_id, encode, "audio/ms-gsm", NULL);
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/ms-gsm",
NULL);
break;
case CODEC_ID_NELLYMOSER:
caps =
gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-nellymoser",
NULL);
gst_ff_aud_caps_new (context, NULL, codec_id, encode,
"audio/x-nellymoser", NULL);
break;
case CODEC_ID_SIPR:
{
caps =
gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-sipro",
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-sipro",
NULL);
if (context) {
gst_caps_set_simple (caps,
@ -1572,7 +1622,7 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
/* FIXME: properties? */
caps =
gst_ff_aud_caps_new (context, codec_id, encode,
gst_ff_aud_caps_new (context, NULL, codec_id, encode,
"audio/x-pn-realaudio", "raversion", G_TYPE_INT, version, NULL);
if (context) {
gst_caps_set_simple (caps,
@ -1609,7 +1659,8 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
/* FIXME: someone please check whether we need additional properties
* in this caps definition. */
caps = gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-dpcm",
caps =
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-dpcm",
"layout", G_TYPE_STRING, layout, NULL);
if (context)
gst_caps_set_simple (caps,
@ -1624,7 +1675,8 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
case CODEC_ID_ALAC:
caps =
gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-alac", NULL);
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-alac",
NULL);
if (context) {
gst_caps_set_simple (caps,
"samplesize", G_TYPE_INT, context->bits_per_coded_sample, NULL);
@ -1648,7 +1700,8 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
break;
case CODEC_ID_TTA:
caps =
gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-tta", NULL);
gst_ff_aud_caps_new (context, NULL, codec_id, encode, "audio/x-tta",
NULL);
if (context) {
gst_caps_set_simple (caps,
"samplesize", G_TYPE_INT, context->bits_per_coded_sample, NULL);
@ -1656,8 +1709,8 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
break;
case CODEC_ID_TWINVQ:
caps =
gst_ff_aud_caps_new (context, codec_id, encode, "audio/x-twin-vq",
NULL);
gst_ff_aud_caps_new (context, NULL, codec_id, encode,
"audio/x-twin-vq", NULL);
break;
default:
GST_DEBUG ("Unknown codec ID %d, please add mapping here", codec_id);
@ -1681,7 +1734,8 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
break;
case AVMEDIA_TYPE_AUDIO:
mime = g_strdup_printf ("audio/x-gst-av-%s", codec->name);
caps = gst_ff_aud_caps_new (context, codec_id, encode, mime, NULL);
caps =
gst_ff_aud_caps_new (context, NULL, codec_id, encode, mime, NULL);
if (context)
gst_caps_set_simple (caps,
"block_align", G_TYPE_INT, context->block_align,
@ -1784,7 +1838,7 @@ gst_ffmpeg_smpfmt_to_audioformat (enum AVSampleFormat sample_fmt)
static GstCaps *
gst_ffmpeg_smpfmt_to_caps (enum AVSampleFormat sample_fmt,
AVCodecContext * context, enum CodecID codec_id)
AVCodecContext * context, AVCodec * codec, enum CodecID codec_id)
{
GstCaps *caps = NULL;
GstAudioFormat format;
@ -1792,7 +1846,7 @@ gst_ffmpeg_smpfmt_to_caps (enum AVSampleFormat sample_fmt,
format = gst_ffmpeg_smpfmt_to_audioformat (sample_fmt);
if (format != GST_AUDIO_FORMAT_UNKNOWN) {
caps = gst_ff_aud_caps_new (context, codec_id, TRUE, "audio/x-raw",
caps = gst_ff_aud_caps_new (context, codec, codec_id, TRUE, "audio/x-raw",
"format", G_TYPE_STRING, gst_audio_format_to_string (format),
"layout", G_TYPE_STRING, "interleaved", NULL);
GST_LOG ("caps for sample_fmt=%d: %" GST_PTR_FORMAT, sample_fmt, caps);
@ -1862,9 +1916,11 @@ gst_ffmpeg_codectype_to_audio_caps (AVCodecContext * context,
if (context) {
/* Specific codec context */
caps = gst_ffmpeg_smpfmt_to_caps (context->sample_fmt, context, codec_id);
caps =
gst_ffmpeg_smpfmt_to_caps (context->sample_fmt, context, codec,
codec_id);
} else {
caps = gst_ff_aud_caps_new (context, 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);
gst_ffmpeg_audio_set_sample_fmts (caps, codec ? codec->sample_fmts : NULL);