summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Hervey <bilboed@bilboed.com>2008-12-17 12:05:12 +0000
committerEdward Hervey <bilboed@bilboed.com>2008-12-17 12:05:12 +0000
commit3d089f4862e8ad4ee4c296962d43e85d0634e596 (patch)
treeb8b9a72c2071fb3c79cde999746b1d38f5c0726d
parent75694feb3b583b2060f1fa27b1e4c0c051f0120e (diff)
downloadgst-libav-3d089f4862e8ad4ee4c296962d43e85d0634e596.tar.gz
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.
-rw-r--r--ChangeLog15
-rw-r--r--ext/ffmpeg/gstffmpegcodecmap.c103
-rw-r--r--ext/ffmpeg/gstffmpegcodecmap.h3
-rw-r--r--ext/ffmpeg/gstffmpegdec.c24
4 files changed, 125 insertions, 20 deletions
diff --git a/ChangeLog b/ChangeLog
index 38614b3..f6c28f1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+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>
* configure.ac:
diff --git a/ext/ffmpeg/gstffmpegcodecmap.c b/ext/ffmpeg/gstffmpegcodecmap.c
index 1d896df..75b7b77 100644
--- a/ext/ffmpeg/gstffmpegcodecmap.c
+++ b/ext/ffmpeg/gstffmpegcodecmap.c
@@ -322,6 +322,7 @@ gst_ff_aud_caps_new (AVCodecContext * context, enum CodecID codec_id,
rates = l_rates;
break;
}
+ case CODEC_ID_EAC3:
case CODEC_ID_AC3:
{
const static gint l_rates[] = { 48000, 44100, 32000 };
@@ -361,6 +362,7 @@ gst_ff_aud_caps_new (AVCodecContext * context, enum CodecID codec_id,
* they support, we whitelist them here. */
switch (codec_id) {
case CODEC_ID_AC3:
+ case CODEC_ID_EAC3:
case CODEC_ID_AAC:
case CODEC_ID_DTS:
maxchannels = 6;
@@ -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);
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:
caps = gst_ff_aud_caps_new (context, codec_id, "audio/atrac3", NULL);
break;
@@ -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);
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_IDCIN:
case CODEC_ID_8BPS:
@@ -1529,6 +1540,7 @@ gst_ffmpeg_smpfmt_to_caps (enum SampleFormat sample_fmt,
GstCaps *caps = NULL;
int bpp = 0;
+ gboolean integer = TRUE;
gboolean signedness = FALSE;
switch (sample_fmt) {
@@ -1537,16 +1549,36 @@ gst_ffmpeg_smpfmt_to_caps (enum SampleFormat sample_fmt,
bpp = 16;
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:
/* .. */
break;
}
if (bpp) {
- caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-raw-int",
- "signed", G_TYPE_BOOLEAN, signedness,
- "endianness", G_TYPE_INT, G_BYTE_ORDER,
- "width", G_TYPE_INT, bpp, "depth", G_TYPE_INT, bpp, NULL);
+ if (integer) {
+ caps = gst_ff_aud_caps_new (context, codec_id, "audio/x-raw-int",
+ "signed", G_TYPE_BOOLEAN, signedness,
+ "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) {
@@ -1603,7 +1635,7 @@ gst_ffmpeg_codectype_to_caps (enum CodecType codec_type,
ctx.channels = -1;
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);
if (temp != NULL) {
gst_caps_append (caps, temp);
@@ -1646,13 +1678,29 @@ gst_ffmpeg_caps_to_smpfmt (const GstCaps * caps,
if (!raw)
return;
- 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 (width == 16 && depth == 16 &&
- endianness == G_BYTE_ORDER && signedness == TRUE) {
- context->sample_fmt = SAMPLE_FMT_S16;
+ if (!strcmp (gst_structure_get_name (structure), "audio/x-raw-float")) {
+ /* FLOAT */
+ if (gst_structure_get_int (structure, "width", &width) &&
+ gst_structure_get_int (structure, "endianness", &endianness)) {
+ if (endianness == G_BYTE_ORDER) {
+ if (width == 32)
+ 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)
} else if (!strcmp (mimetype, "audio/x-ac3")) {
id = CODEC_ID_AC3;
audio = TRUE;
+ } else if (!strcmp (mimetype, "audio/x-eac3")) {
+ id = CODEC_ID_EAC3;
+ audio = TRUE;
} else if (!strcmp (mimetype, "audio/atrac3")) {
id = CODEC_ID_ATRAC3;
audio = TRUE;
@@ -2821,6 +2872,9 @@ gst_ffmpeg_caps_to_codecid (const GstCaps * caps, AVCodecContext * context)
} else if (!strcmp (mimetype, "audio/AMR-WB")) {
id = CODEC_ID_AMR_WB;
audio = TRUE;
+ } else if (!strcmp (mimetype, "audio/qcelp")) {
+ id = CODEC_ID_QCELP;
+ audio = TRUE;
} else if (!strcmp (mimetype, "video/x-h264")) {
id = CODEC_ID_H264;
video = TRUE;
@@ -3236,3 +3290,28 @@ gst_ffmpeg_avpicture_fill (AVPicture * picture,
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;
+}
diff --git a/ext/ffmpeg/gstffmpegcodecmap.h b/ext/ffmpeg/gstffmpegcodecmap.h
index cf98216..46c5171 100644
--- a/ext/ffmpeg/gstffmpegcodecmap.h
+++ b/ext/ffmpeg/gstffmpegcodecmap.h
@@ -163,4 +163,7 @@ gst_ffmpeg_time_gst_to_ff (guint64 time, AVRational base)
void
gst_ffmpeg_init_pix_fmt_info();
+gint
+av_smp_format_depth(enum SampleFormat smp_fmt);
+
#endif /* __GST_FFMPEG_CODECMAP_H__ */
diff --git a/ext/ffmpeg/gstffmpegdec.c b/ext/ffmpeg/gstffmpegdec.c
index a70136b..7a14d2e 100644
--- a/ext/ffmpeg/gstffmpegdec.c
+++ b/ext/ffmpeg/gstffmpegdec.c
@@ -67,6 +67,7 @@ struct _GstFFMpegDec
{
gint channels;
gint samplerate;
+ gint depth;
} audio;
} format;
gboolean waiting_for_key;
@@ -587,6 +588,7 @@ gst_ffmpegdec_open (GstFFMpegDec * ffmpegdec)
case CODEC_TYPE_AUDIO:
ffmpegdec->format.audio.samplerate = 0;
ffmpegdec->format.audio.channels = 0;
+ ffmpegdec->format.audio.depth = 0;
break;
default:
break;
@@ -707,8 +709,7 @@ gst_ffmpegdec_setcaps (GstPad * pad, GstCaps * caps)
GST_DEBUG_OBJECT (ffmpegdec, "enabled direct rendering");
ffmpegdec->current_dr = TRUE;
}
- }
- else {
+ } else {
GST_DEBUG_OBJECT (ffmpegdec, "direct rendering not supported");
}
}
@@ -1075,16 +1076,22 @@ gst_ffmpegdec_negotiate (GstFFMpegDec * ffmpegdec)
ffmpegdec->format.video.pix_fmt = ffmpegdec->context->pix_fmt;
break;
case CODEC_TYPE_AUDIO:
+ {
+ gint depth = av_smp_format_depth (ffmpegdec->context->sample_fmt);
if (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)
return TRUE;
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->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.channels = ffmpegdec->context->channels;
+ ffmpegdec->format.audio.depth = depth;
+ }
break;
default:
break;
@@ -1738,7 +1745,7 @@ clip_audio_buffer (GstFFMpegDec * dec, GstBuffer * buf, GstClockTime in_ts,
/* bring clipped time to bytes */
diff =
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 " %"
G_GINT64_FORMAT " bytes", GST_TIME_ARGS (ctime), diff);
@@ -1750,7 +1757,7 @@ clip_audio_buffer (GstFFMpegDec * dec, GstBuffer * buf, GstClockTime in_ts,
/* bring clipped time to bytes */
diff =
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 " %"
G_GINT64_FORMAT " bytes", GST_TIME_ARGS (cstop), diff);
@@ -1824,7 +1831,8 @@ gst_ffmpegdec_audio_frame (GstFFMpegDec * ffmpegdec,
* 1) calculate based on number of samples
*/
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,
"Buffer created. Size:%d , timestamp:%" GST_TIME_FORMAT " , duration:%"