Commit 3d089f48 authored by Edward Hervey's avatar Edward Hervey 🤘

ext/ffmpeg/gstffmpegcodecmap.*: Add mapping for EAC3 and QCELP audio codecs.

Original commit message from CVS:
* ext/ffmpeg/gstffmpegcodecmap.c: (gst_ff_aud_caps_new),
(gst_ffmpeg_codecid_to_caps), (gst_ffmpeg_smpfmt_to_caps),
(gst_ffmpeg_codectype_to_caps), (gst_ffmpeg_caps_to_smpfmt),
(gst_ffmpeg_caps_to_codecid), (av_smp_format_depth):
* ext/ffmpeg/gstffmpegcodecmap.h:
Add mapping for EAC3 and QCELP audio codecs.
Add conversion functions for all available audo SampleFormat.
* ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_open),
(gst_ffmpegdec_setcaps), (gst_ffmpegdec_negotiate),
(clip_audio_buffer), (gst_ffmpegdec_audio_frame):
Remove assumptions that we can only handle stereo 16bit signed integer
audio, and store the depth locally.
parent 75694feb
2008-12-17 Edward Hervey <edward.hervey@collabora.co.uk>
* ext/ffmpeg/gstffmpegcodecmap.c: (gst_ff_aud_caps_new),
(gst_ffmpeg_codecid_to_caps), (gst_ffmpeg_smpfmt_to_caps),
(gst_ffmpeg_codectype_to_caps), (gst_ffmpeg_caps_to_smpfmt),
(gst_ffmpeg_caps_to_codecid), (av_smp_format_depth):
* ext/ffmpeg/gstffmpegcodecmap.h:
Add mapping for EAC3 and QCELP audio codecs.
Add conversion functions for all available audo SampleFormat.
* ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_open),
(gst_ffmpegdec_setcaps), (gst_ffmpegdec_negotiate),
(clip_audio_buffer), (gst_ffmpegdec_audio_frame):
Remove assumptions that we can only handle stereo 16bit signed integer
audio, and store the depth locally.
2008-12-16 Stefan Kost <ensonic@users.sf.net> 2008-12-16 Stefan Kost <ensonic@users.sf.net>
* configure.ac: * configure.ac:
......
...@@ -322,6 +322,7 @@ gst_ff_aud_caps_new (AVCodecContext * context, enum CodecID codec_id, ...@@ -322,6 +322,7 @@ gst_ff_aud_caps_new (AVCodecContext * context, enum CodecID codec_id,
rates = l_rates; rates = l_rates;
break; break;
} }
case CODEC_ID_EAC3:
case CODEC_ID_AC3: case CODEC_ID_AC3:
{ {
const static gint l_rates[] = { 48000, 44100, 32000 }; const static gint l_rates[] = { 48000, 44100, 32000 };
...@@ -361,6 +362,7 @@ gst_ff_aud_caps_new (AVCodecContext * context, enum CodecID codec_id, ...@@ -361,6 +362,7 @@ gst_ff_aud_caps_new (AVCodecContext * context, enum CodecID codec_id,
* they support, we whitelist them here. */ * they support, we whitelist them here. */
switch (codec_id) { switch (codec_id) {
case CODEC_ID_AC3: case CODEC_ID_AC3:
case CODEC_ID_EAC3:
case CODEC_ID_AAC: case CODEC_ID_AAC:
case CODEC_ID_DTS: case CODEC_ID_DTS:
maxchannels = 6; maxchannels = 6;
...@@ -560,6 +562,11 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id, ...@@ -560,6 +562,11 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-ac3", NULL); caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-ac3", NULL);
break; break;
case CODEC_ID_EAC3:
/* FIXME: bitrate */
caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-eac3", NULL);
break;
case CODEC_ID_ATRAC3: case CODEC_ID_ATRAC3:
caps = gst_ff_aud_caps_new (context, codec_id, "audio/atrac3", NULL); caps = gst_ff_aud_caps_new (context, codec_id, "audio/atrac3", NULL);
break; break;
...@@ -986,6 +993,10 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id, ...@@ -986,6 +993,10 @@ gst_ffmpeg_codecid_to_caps (enum CodecID codec_id,
gst_ff_aud_caps_new (context, codec_id, "audio/x-truespeech", NULL); gst_ff_aud_caps_new (context, codec_id, "audio/x-truespeech", NULL);
break; break;
case CODEC_ID_QCELP:
caps = gst_ff_aud_caps_new (context, codec_id, "audio/qcelp", NULL);
break;
case CODEC_ID_WS_VQA: case CODEC_ID_WS_VQA:
case CODEC_ID_IDCIN: case CODEC_ID_IDCIN:
case CODEC_ID_8BPS: case CODEC_ID_8BPS:
...@@ -1529,6 +1540,7 @@ gst_ffmpeg_smpfmt_to_caps (enum SampleFormat sample_fmt, ...@@ -1529,6 +1540,7 @@ gst_ffmpeg_smpfmt_to_caps (enum SampleFormat sample_fmt,
GstCaps *caps = NULL; GstCaps *caps = NULL;
int bpp = 0; int bpp = 0;
gboolean integer = TRUE;
gboolean signedness = FALSE; gboolean signedness = FALSE;
switch (sample_fmt) { switch (sample_fmt) {
...@@ -1537,16 +1549,36 @@ gst_ffmpeg_smpfmt_to_caps (enum SampleFormat sample_fmt, ...@@ -1537,16 +1549,36 @@ gst_ffmpeg_smpfmt_to_caps (enum SampleFormat sample_fmt,
bpp = 16; bpp = 16;
break; break;
case SAMPLE_FMT_S32:
signedness = TRUE;
bpp = 32;
break;
case SAMPLE_FMT_FLT:
integer = FALSE;
bpp = 32;
break;
case SAMPLE_FMT_DBL:
integer = FALSE;
bpp = 64;
break;
default: default:
/* .. */ /* .. */
break; break;
} }
if (bpp) { if (bpp) {
caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-raw-int", if (integer) {
"signed", G_TYPE_BOOLEAN, signedness, caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-raw-int",
"endianness", G_TYPE_INT, G_BYTE_ORDER, "signed", G_TYPE_BOOLEAN, signedness,
"width", G_TYPE_INT, bpp, "depth", G_TYPE_INT, bpp, NULL); "endianness", G_TYPE_INT, G_BYTE_ORDER,
"width", G_TYPE_INT, bpp, "depth", G_TYPE_INT, bpp, NULL);
} else {
caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-raw-float",
"endianness", G_TYPE_INT, G_BYTE_ORDER,
"width", G_TYPE_INT, bpp, NULL);
}
} }
if (caps != NULL) { if (caps != NULL) {
...@@ -1603,7 +1635,7 @@ gst_ffmpeg_codectype_to_caps (enum CodecType codec_type, ...@@ -1603,7 +1635,7 @@ gst_ffmpeg_codectype_to_caps (enum CodecType codec_type,
ctx.channels = -1; ctx.channels = -1;
caps = gst_caps_new_empty (); caps = gst_caps_new_empty ();
for (i = 0; i <= SAMPLE_FMT_S16; i++) { for (i = 0; i <= SAMPLE_FMT_DBL; i++) {
temp = gst_ffmpeg_smpfmt_to_caps (i, encode ? &ctx : NULL, codec_id); temp = gst_ffmpeg_smpfmt_to_caps (i, encode ? &ctx : NULL, codec_id);
if (temp != NULL) { if (temp != NULL) {
gst_caps_append (caps, temp); gst_caps_append (caps, temp);
...@@ -1646,13 +1678,29 @@ gst_ffmpeg_caps_to_smpfmt (const GstCaps * caps, ...@@ -1646,13 +1678,29 @@ gst_ffmpeg_caps_to_smpfmt (const GstCaps * caps,
if (!raw) if (!raw)
return; return;
if (gst_structure_get_int (structure, "width", &width) && if (!strcmp (gst_structure_get_name (structure), "audio/x-raw-float")) {
gst_structure_get_int (structure, "depth", &depth) && /* FLOAT */
gst_structure_get_boolean (structure, "signed", &signedness) && if (gst_structure_get_int (structure, "width", &width) &&
gst_structure_get_int (structure, "endianness", &endianness)) { gst_structure_get_int (structure, "endianness", &endianness)) {
if (width == 16 && depth == 16 && if (endianness == G_BYTE_ORDER) {
endianness == G_BYTE_ORDER && signedness == TRUE) { if (width == 32)
context->sample_fmt = SAMPLE_FMT_S16; context->sample_fmt = SAMPLE_FMT_FLT;
else if (width == 64)
context->sample_fmt = SAMPLE_FMT_DBL;
}
}
} else {
/* INT */
if (gst_structure_get_int (structure, "width", &width) &&
gst_structure_get_int (structure, "depth", &depth) &&
gst_structure_get_boolean (structure, "signed", &signedness) &&
gst_structure_get_int (structure, "endianness", &endianness)) {
if ((endianness == G_BYTE_ORDER) && (signedness == TRUE)) {
if ((width == 16) && (depth == 16))
context->sample_fmt = SAMPLE_FMT_S16;
else if ((width == 32) && (depth == 32))
context->sample_fmt = SAMPLE_FMT_S32;
}
} }
} }
} }
...@@ -2550,6 +2598,9 @@ gst_ffmpeg_caps_to_codecid (const GstCaps * caps, AVCodecContext * context) ...@@ -2550,6 +2598,9 @@ gst_ffmpeg_caps_to_codecid (const GstCaps * caps, AVCodecContext * context)
} else if (!strcmp (mimetype, "audio/x-ac3")) { } else if (!strcmp (mimetype, "audio/x-ac3")) {
id = CODEC_ID_AC3; id = CODEC_ID_AC3;
audio = TRUE; audio = TRUE;
} else if (!strcmp (mimetype, "audio/x-eac3")) {
id = CODEC_ID_EAC3;
audio = TRUE;
} else if (!strcmp (mimetype, "audio/atrac3")) { } else if (!strcmp (mimetype, "audio/atrac3")) {
id = CODEC_ID_ATRAC3; id = CODEC_ID_ATRAC3;
audio = TRUE; audio = TRUE;
...@@ -2821,6 +2872,9 @@ gst_ffmpeg_caps_to_codecid (const GstCaps * caps, AVCodecContext * context) ...@@ -2821,6 +2872,9 @@ gst_ffmpeg_caps_to_codecid (const GstCaps * caps, AVCodecContext * context)
} else if (!strcmp (mimetype, "audio/AMR-WB")) { } else if (!strcmp (mimetype, "audio/AMR-WB")) {
id = CODEC_ID_AMR_WB; id = CODEC_ID_AMR_WB;
audio = TRUE; audio = TRUE;
} else if (!strcmp (mimetype, "audio/qcelp")) {
id = CODEC_ID_QCELP;
audio = TRUE;
} else if (!strcmp (mimetype, "video/x-h264")) { } else if (!strcmp (mimetype, "video/x-h264")) {
id = CODEC_ID_H264; id = CODEC_ID_H264;
video = TRUE; video = TRUE;
...@@ -3236,3 +3290,28 @@ gst_ffmpeg_avpicture_fill (AVPicture * picture, ...@@ -3236,3 +3290,28 @@ gst_ffmpeg_avpicture_fill (AVPicture * picture,
return 0; return 0;
} }
gint
av_smp_format_depth (enum SampleFormat smp_fmt)
{
gint depth = -1;
switch (smp_fmt) {
case SAMPLE_FMT_U8:
depth = 1;
break;
case SAMPLE_FMT_S16:
depth = 2;
break;
case SAMPLE_FMT_S32:
case SAMPLE_FMT_FLT:
depth = 4;
break;
case SAMPLE_FMT_DBL:
depth = 8;
break;
default:
GST_ERROR ("UNHANDLED SAMPLE FORMAT !");
break;
}
return depth;
}
...@@ -163,4 +163,7 @@ gst_ffmpeg_time_gst_to_ff (guint64 time, AVRational base) ...@@ -163,4 +163,7 @@ gst_ffmpeg_time_gst_to_ff (guint64 time, AVRational base)
void void
gst_ffmpeg_init_pix_fmt_info(); gst_ffmpeg_init_pix_fmt_info();
gint
av_smp_format_depth(enum SampleFormat smp_fmt);
#endif /* __GST_FFMPEG_CODECMAP_H__ */ #endif /* __GST_FFMPEG_CODECMAP_H__ */
...@@ -67,6 +67,7 @@ struct _GstFFMpegDec ...@@ -67,6 +67,7 @@ struct _GstFFMpegDec
{ {
gint channels; gint channels;
gint samplerate; gint samplerate;
gint depth;
} audio; } audio;
} format; } format;
gboolean waiting_for_key; gboolean waiting_for_key;
...@@ -587,6 +588,7 @@ gst_ffmpegdec_open (GstFFMpegDec * ffmpegdec) ...@@ -587,6 +588,7 @@ gst_ffmpegdec_open (GstFFMpegDec * ffmpegdec)
case CODEC_TYPE_AUDIO: case CODEC_TYPE_AUDIO:
ffmpegdec->format.audio.samplerate = 0; ffmpegdec->format.audio.samplerate = 0;
ffmpegdec->format.audio.channels = 0; ffmpegdec->format.audio.channels = 0;
ffmpegdec->format.audio.depth = 0;
break; break;
default: default:
break; break;
...@@ -707,8 +709,7 @@ gst_ffmpegdec_setcaps (GstPad * pad, GstCaps * caps) ...@@ -707,8 +709,7 @@ gst_ffmpegdec_setcaps (GstPad * pad, GstCaps * caps)
GST_DEBUG_OBJECT (ffmpegdec, "enabled direct rendering"); GST_DEBUG_OBJECT (ffmpegdec, "enabled direct rendering");
ffmpegdec->current_dr = TRUE; ffmpegdec->current_dr = TRUE;
} }
} } else {
else {
GST_DEBUG_OBJECT (ffmpegdec, "direct rendering not supported"); GST_DEBUG_OBJECT (ffmpegdec, "direct rendering not supported");
} }
} }
...@@ -1075,16 +1076,22 @@ gst_ffmpegdec_negotiate (GstFFMpegDec * ffmpegdec) ...@@ -1075,16 +1076,22 @@ gst_ffmpegdec_negotiate (GstFFMpegDec * ffmpegdec)
ffmpegdec->format.video.pix_fmt = ffmpegdec->context->pix_fmt; ffmpegdec->format.video.pix_fmt = ffmpegdec->context->pix_fmt;
break; break;
case CODEC_TYPE_AUDIO: case CODEC_TYPE_AUDIO:
{
gint depth = av_smp_format_depth (ffmpegdec->context->sample_fmt);
if (ffmpegdec->format.audio.samplerate == if (ffmpegdec->format.audio.samplerate ==
ffmpegdec->context->sample_rate && ffmpegdec->context->sample_rate &&
ffmpegdec->format.audio.channels == ffmpegdec->context->channels) ffmpegdec->format.audio.channels == ffmpegdec->context->channels &&
ffmpegdec->format.audio.depth == depth)
return TRUE; return TRUE;
GST_DEBUG_OBJECT (ffmpegdec, GST_DEBUG_OBJECT (ffmpegdec,
"Renegotiating audio from %dHz@%dchannels to %dHz@%dchannels", "Renegotiating audio from %dHz@%dchannels (%d) to %dHz@%dchannels (%d)",
ffmpegdec->format.audio.samplerate, ffmpegdec->format.audio.channels, ffmpegdec->format.audio.samplerate, ffmpegdec->format.audio.channels,
ffmpegdec->context->sample_rate, ffmpegdec->context->channels); ffmpegdec->format.audio.depth,
ffmpegdec->context->sample_rate, ffmpegdec->context->channels, depth);
ffmpegdec->format.audio.samplerate = ffmpegdec->context->sample_rate; ffmpegdec->format.audio.samplerate = ffmpegdec->context->sample_rate;
ffmpegdec->format.audio.channels = ffmpegdec->context->channels; ffmpegdec->format.audio.channels = ffmpegdec->context->channels;
ffmpegdec->format.audio.depth = depth;
}
break; break;
default: default:
break; break;
...@@ -1738,7 +1745,7 @@ clip_audio_buffer (GstFFMpegDec * dec, GstBuffer * buf, GstClockTime in_ts, ...@@ -1738,7 +1745,7 @@ clip_audio_buffer (GstFFMpegDec * dec, GstBuffer * buf, GstClockTime in_ts,
/* bring clipped time to bytes */ /* bring clipped time to bytes */
diff = diff =
gst_util_uint64_scale_int (diff, dec->format.audio.samplerate, gst_util_uint64_scale_int (diff, dec->format.audio.samplerate,
GST_SECOND) * (2 * dec->format.audio.channels); GST_SECOND) * (dec->format.audio.depth * dec->format.audio.channels);
GST_DEBUG_OBJECT (dec, "clipping start to %" GST_TIME_FORMAT " %" GST_DEBUG_OBJECT (dec, "clipping start to %" GST_TIME_FORMAT " %"
G_GINT64_FORMAT " bytes", GST_TIME_ARGS (ctime), diff); G_GINT64_FORMAT " bytes", GST_TIME_ARGS (ctime), diff);
...@@ -1750,7 +1757,7 @@ clip_audio_buffer (GstFFMpegDec * dec, GstBuffer * buf, GstClockTime in_ts, ...@@ -1750,7 +1757,7 @@ clip_audio_buffer (GstFFMpegDec * dec, GstBuffer * buf, GstClockTime in_ts,
/* bring clipped time to bytes */ /* bring clipped time to bytes */
diff = diff =
gst_util_uint64_scale_int (diff, dec->format.audio.samplerate, gst_util_uint64_scale_int (diff, dec->format.audio.samplerate,
GST_SECOND) * (2 * dec->format.audio.channels); GST_SECOND) * (dec->format.audio.depth * dec->format.audio.channels);
GST_DEBUG_OBJECT (dec, "clipping stop to %" GST_TIME_FORMAT " %" GST_DEBUG_OBJECT (dec, "clipping stop to %" GST_TIME_FORMAT " %"
G_GINT64_FORMAT " bytes", GST_TIME_ARGS (cstop), diff); G_GINT64_FORMAT " bytes", GST_TIME_ARGS (cstop), diff);
...@@ -1824,7 +1831,8 @@ gst_ffmpegdec_audio_frame (GstFFMpegDec * ffmpegdec, ...@@ -1824,7 +1831,8 @@ gst_ffmpegdec_audio_frame (GstFFMpegDec * ffmpegdec,
* 1) calculate based on number of samples * 1) calculate based on number of samples
*/ */
in_duration = gst_util_uint64_scale_int (have_data, GST_SECOND, in_duration = gst_util_uint64_scale_int (have_data, GST_SECOND,
2 * ffmpegdec->context->channels * ffmpegdec->context->sample_rate); ffmpegdec->format.audio.depth * ffmpegdec->format.audio.channels *
ffmpegdec->format.audio.samplerate);
GST_DEBUG_OBJECT (ffmpegdec, GST_DEBUG_OBJECT (ffmpegdec,
"Buffer created. Size:%d , timestamp:%" GST_TIME_FORMAT " , duration:%" "Buffer created. Size:%d , timestamp:%" GST_TIME_FORMAT " , duration:%"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment