mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-24 09:34:25 +00:00
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.
This commit is contained in:
parent
75694feb3b
commit
3d089f4862
4 changed files with 125 additions and 20 deletions
15
ChangeLog
15
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:
|
||||
|
|
|
@ -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) {
|
||||
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 (!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 (width == 16 && depth == 16 &&
|
||||
endianness == G_BYTE_ORDER && signedness == TRUE) {
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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:%"
|
||||
|
|
Loading…
Reference in a new issue