diff options
author | Edward Hervey <bilboed@bilboed.com> | 2008-12-17 12:05:12 +0000 |
---|---|---|
committer | Edward Hervey <bilboed@bilboed.com> | 2008-12-17 12:05:12 +0000 |
commit | 3d089f4862e8ad4ee4c296962d43e85d0634e596 (patch) | |
tree | b8b9a72c2071fb3c79cde999746b1d38f5c0726d | |
parent | 75694feb3b583b2060f1fa27b1e4c0c051f0120e (diff) | |
download | gst-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-- | ChangeLog | 15 | ||||
-rw-r--r-- | ext/ffmpeg/gstffmpegcodecmap.c | 103 | ||||
-rw-r--r-- | ext/ffmpeg/gstffmpegcodecmap.h | 3 | ||||
-rw-r--r-- | ext/ffmpeg/gstffmpegdec.c | 24 |
4 files changed, 125 insertions, 20 deletions
@@ -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:%" |