mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-25 16:48:11 +00:00
audioparsers: fix some parsers
This commit is contained in:
parent
bb8cecb424
commit
63a17f4ec9
3 changed files with 66 additions and 79 deletions
|
@ -91,12 +91,7 @@ gint gst_aac_parse_get_frame_overhead (GstBaseParse * parse,
|
||||||
|
|
||||||
gboolean gst_aac_parse_event (GstBaseParse * parse, GstEvent * event);
|
gboolean gst_aac_parse_event (GstBaseParse * parse, GstEvent * event);
|
||||||
|
|
||||||
#define _do_init(bla) \
|
G_DEFINE_TYPE (GstAacParse, gst_aac_parse, GST_TYPE_BASE_PARSE);
|
||||||
GST_DEBUG_CATEGORY_INIT (aacparse_debug, "aacparse", 0, \
|
|
||||||
"AAC audio stream parser");
|
|
||||||
|
|
||||||
GST_BOILERPLATE_FULL (GstAacParse, gst_aac_parse, GstBaseParse,
|
|
||||||
GST_TYPE_BASE_PARSE, _do_init);
|
|
||||||
|
|
||||||
static inline gint
|
static inline gint
|
||||||
gst_aac_parse_get_sample_rate_from_index (guint sr_idx)
|
gst_aac_parse_get_sample_rate_from_index (guint sr_idx)
|
||||||
|
@ -112,14 +107,18 @@ gst_aac_parse_get_sample_rate_from_index (guint sr_idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_aac_parse_base_init:
|
* gst_aac_parse_class_init:
|
||||||
* @klass: #GstElementClass.
|
* @klass: #GstAacParseClass.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
gst_aac_parse_base_init (gpointer klass)
|
gst_aac_parse_class_init (GstAacParseClass * klass)
|
||||||
{
|
{
|
||||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||||
|
GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass);
|
||||||
|
|
||||||
|
GST_DEBUG_CATEGORY_INIT (aacparse_debug, "aacparse", 0,
|
||||||
|
"AAC audio stream parser");
|
||||||
|
|
||||||
gst_element_class_add_pad_template (element_class,
|
gst_element_class_add_pad_template (element_class,
|
||||||
gst_static_pad_template_get (&sink_template));
|
gst_static_pad_template_get (&sink_template));
|
||||||
|
@ -129,18 +128,6 @@ gst_aac_parse_base_init (gpointer klass)
|
||||||
gst_element_class_set_details_simple (element_class,
|
gst_element_class_set_details_simple (element_class,
|
||||||
"AAC audio stream parser", "Codec/Parser/Audio",
|
"AAC audio stream parser", "Codec/Parser/Audio",
|
||||||
"Advanced Audio Coding parser", "Stefan Kost <stefan.kost@nokia.com>");
|
"Advanced Audio Coding parser", "Stefan Kost <stefan.kost@nokia.com>");
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gst_aac_parse_class_init:
|
|
||||||
* @klass: #GstAacParseClass.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
gst_aac_parse_class_init (GstAacParseClass * klass)
|
|
||||||
{
|
|
||||||
GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass);
|
|
||||||
|
|
||||||
parse_class->start = GST_DEBUG_FUNCPTR (gst_aac_parse_start);
|
parse_class->start = GST_DEBUG_FUNCPTR (gst_aac_parse_start);
|
||||||
parse_class->stop = GST_DEBUG_FUNCPTR (gst_aac_parse_stop);
|
parse_class->stop = GST_DEBUG_FUNCPTR (gst_aac_parse_stop);
|
||||||
|
@ -158,7 +145,7 @@ gst_aac_parse_class_init (GstAacParseClass * klass)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
gst_aac_parse_init (GstAacParse * aacparse, GstAacParseClass * klass)
|
gst_aac_parse_init (GstAacParse * aacparse)
|
||||||
{
|
{
|
||||||
GST_DEBUG ("initialized");
|
GST_DEBUG ("initialized");
|
||||||
}
|
}
|
||||||
|
@ -253,15 +240,19 @@ gst_aac_parse_sink_setcaps (GstBaseParse * parse, GstCaps * caps)
|
||||||
GstBuffer *buf = gst_value_get_buffer (value);
|
GstBuffer *buf = gst_value_get_buffer (value);
|
||||||
|
|
||||||
if (buf) {
|
if (buf) {
|
||||||
const guint8 *buffer = GST_BUFFER_DATA (buf);
|
guint8 *data;
|
||||||
|
gsize size;
|
||||||
guint sr_idx;
|
guint sr_idx;
|
||||||
|
|
||||||
sr_idx = ((buffer[0] & 0x07) << 1) | ((buffer[1] & 0x80) >> 7);
|
data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
|
||||||
aacparse->object_type = (buffer[0] & 0xf8) >> 3;
|
|
||||||
|
sr_idx = ((data[0] & 0x07) << 1) | ((data[1] & 0x80) >> 7);
|
||||||
|
aacparse->object_type = (data[0] & 0xf8) >> 3;
|
||||||
aacparse->sample_rate = gst_aac_parse_get_sample_rate_from_index (sr_idx);
|
aacparse->sample_rate = gst_aac_parse_get_sample_rate_from_index (sr_idx);
|
||||||
aacparse->channels = (buffer[1] & 0x78) >> 3;
|
aacparse->channels = (data[1] & 0x78) >> 3;
|
||||||
aacparse->header_type = DSPAAC_HEADER_NONE;
|
aacparse->header_type = DSPAAC_HEADER_NONE;
|
||||||
aacparse->mpegversion = 4;
|
aacparse->mpegversion = 4;
|
||||||
|
gst_buffer_unmap (buf, data, size);
|
||||||
|
|
||||||
GST_DEBUG ("codec_data: object_type=%d, sample_rate=%d, channels=%d",
|
GST_DEBUG ("codec_data: object_type=%d, sample_rate=%d, channels=%d",
|
||||||
aacparse->object_type, aacparse->sample_rate, aacparse->channels);
|
aacparse->object_type, aacparse->sample_rate, aacparse->channels);
|
||||||
|
@ -573,7 +564,8 @@ gboolean
|
||||||
gst_aac_parse_check_valid_frame (GstBaseParse * parse,
|
gst_aac_parse_check_valid_frame (GstBaseParse * parse,
|
||||||
GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
|
GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
|
||||||
{
|
{
|
||||||
const guint8 *data;
|
guint8 *data;
|
||||||
|
gsize size;
|
||||||
GstAacParse *aacparse;
|
GstAacParse *aacparse;
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
gboolean lost_sync;
|
gboolean lost_sync;
|
||||||
|
@ -581,27 +573,27 @@ gst_aac_parse_check_valid_frame (GstBaseParse * parse,
|
||||||
|
|
||||||
aacparse = GST_AAC_PARSE (parse);
|
aacparse = GST_AAC_PARSE (parse);
|
||||||
buffer = frame->buffer;
|
buffer = frame->buffer;
|
||||||
data = GST_BUFFER_DATA (buffer);
|
|
||||||
|
data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
|
||||||
|
|
||||||
lost_sync = GST_BASE_PARSE_LOST_SYNC (parse);
|
lost_sync = GST_BASE_PARSE_LOST_SYNC (parse);
|
||||||
|
|
||||||
if (aacparse->header_type == DSPAAC_HEADER_ADIF ||
|
if (aacparse->header_type == DSPAAC_HEADER_ADIF ||
|
||||||
aacparse->header_type == DSPAAC_HEADER_NONE) {
|
aacparse->header_type == DSPAAC_HEADER_NONE) {
|
||||||
/* There is nothing to parse */
|
/* There is nothing to parse */
|
||||||
*framesize = GST_BUFFER_SIZE (buffer);
|
*framesize = size;
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
|
|
||||||
} else if (aacparse->header_type == DSPAAC_HEADER_NOT_PARSED || lost_sync) {
|
} else if (aacparse->header_type == DSPAAC_HEADER_NOT_PARSED || lost_sync) {
|
||||||
|
|
||||||
ret = gst_aac_parse_detect_stream (aacparse, data, GST_BUFFER_SIZE (buffer),
|
ret = gst_aac_parse_detect_stream (aacparse, data, size,
|
||||||
GST_BASE_PARSE_DRAINING (parse), framesize, skipsize);
|
GST_BASE_PARSE_DRAINING (parse), framesize, skipsize);
|
||||||
|
|
||||||
} else if (aacparse->header_type == DSPAAC_HEADER_ADTS) {
|
} else if (aacparse->header_type == DSPAAC_HEADER_ADTS) {
|
||||||
guint needed_data = 1024;
|
guint needed_data = 1024;
|
||||||
|
|
||||||
ret = gst_aac_parse_check_adts_frame (aacparse, data,
|
ret = gst_aac_parse_check_adts_frame (aacparse, data, size,
|
||||||
GST_BUFFER_SIZE (buffer), GST_BASE_PARSE_DRAINING (parse),
|
GST_BASE_PARSE_DRAINING (parse), framesize, &needed_data);
|
||||||
framesize, &needed_data);
|
|
||||||
|
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
GST_DEBUG ("buffer didn't contain valid frame");
|
GST_DEBUG ("buffer didn't contain valid frame");
|
||||||
|
@ -613,6 +605,7 @@ gst_aac_parse_check_valid_frame (GstBaseParse * parse,
|
||||||
GST_DEBUG ("buffer didn't contain valid frame");
|
GST_DEBUG ("buffer didn't contain valid frame");
|
||||||
gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse), 1024);
|
gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse), 1024);
|
||||||
}
|
}
|
||||||
|
gst_buffer_unmap (buffer, data, size);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -648,6 +641,8 @@ gst_aac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
|
||||||
GstBuffer *buffer;
|
GstBuffer *buffer;
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
gint rate, channels;
|
gint rate, channels;
|
||||||
|
guint8 *data;
|
||||||
|
gsize size;
|
||||||
|
|
||||||
aacparse = GST_AAC_PARSE (parse);
|
aacparse = GST_AAC_PARSE (parse);
|
||||||
buffer = frame->buffer;
|
buffer = frame->buffer;
|
||||||
|
@ -658,8 +653,11 @@ gst_aac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
|
||||||
/* see above */
|
/* see above */
|
||||||
frame->overhead = 7;
|
frame->overhead = 7;
|
||||||
|
|
||||||
gst_aac_parse_parse_adts_header (aacparse, GST_BUFFER_DATA (buffer),
|
data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
|
||||||
|
gst_aac_parse_parse_adts_header (aacparse, data,
|
||||||
&rate, &channels, NULL, NULL);
|
&rate, &channels, NULL, NULL);
|
||||||
|
gst_buffer_unmap (buffer, data, size);
|
||||||
|
|
||||||
GST_LOG_OBJECT (aacparse, "rate: %d, chans: %d", rate, channels);
|
GST_LOG_OBJECT (aacparse, "rate: %d, chans: %d", rate, channels);
|
||||||
|
|
||||||
if (G_UNLIKELY (rate != aacparse->sample_rate
|
if (G_UNLIKELY (rate != aacparse->sample_rate
|
||||||
|
|
|
@ -164,12 +164,20 @@ static gboolean gst_ac3_parse_check_valid_frame (GstBaseParse * parse,
|
||||||
static GstFlowReturn gst_ac3_parse_parse_frame (GstBaseParse * parse,
|
static GstFlowReturn gst_ac3_parse_parse_frame (GstBaseParse * parse,
|
||||||
GstBaseParseFrame * frame);
|
GstBaseParseFrame * frame);
|
||||||
|
|
||||||
GST_BOILERPLATE (GstAc3Parse, gst_ac3_parse, GstBaseParse, GST_TYPE_BASE_PARSE);
|
#define gst_ac3_parse_parent_class parent_class
|
||||||
|
G_DEFINE_TYPE (GstAc3Parse, gst_ac3_parse, GST_TYPE_BASE_PARSE);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_ac3_parse_base_init (gpointer klass)
|
gst_ac3_parse_class_init (GstAc3ParseClass * klass)
|
||||||
{
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||||
|
GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass);
|
||||||
|
|
||||||
|
GST_DEBUG_CATEGORY_INIT (ac3_parse_debug, "ac3parse", 0,
|
||||||
|
"AC3 audio stream parser");
|
||||||
|
|
||||||
|
object_class->finalize = gst_ac3_parse_finalize;
|
||||||
|
|
||||||
gst_element_class_add_pad_template (element_class,
|
gst_element_class_add_pad_template (element_class,
|
||||||
gst_static_pad_template_get (&sink_template));
|
gst_static_pad_template_get (&sink_template));
|
||||||
|
@ -179,18 +187,6 @@ gst_ac3_parse_base_init (gpointer klass)
|
||||||
gst_element_class_set_details_simple (element_class,
|
gst_element_class_set_details_simple (element_class,
|
||||||
"AC3 audio stream parser", "Codec/Parser/Audio",
|
"AC3 audio stream parser", "Codec/Parser/Audio",
|
||||||
"AC3 parser", "Tim-Philipp Müller <tim centricular net>");
|
"AC3 parser", "Tim-Philipp Müller <tim centricular net>");
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_ac3_parse_class_init (GstAc3ParseClass * klass)
|
|
||||||
{
|
|
||||||
GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass);
|
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_INIT (ac3_parse_debug, "ac3parse", 0,
|
|
||||||
"AC3 audio stream parser");
|
|
||||||
|
|
||||||
object_class->finalize = gst_ac3_parse_finalize;
|
|
||||||
|
|
||||||
parse_class->start = GST_DEBUG_FUNCPTR (gst_ac3_parse_start);
|
parse_class->start = GST_DEBUG_FUNCPTR (gst_ac3_parse_start);
|
||||||
parse_class->stop = GST_DEBUG_FUNCPTR (gst_ac3_parse_stop);
|
parse_class->stop = GST_DEBUG_FUNCPTR (gst_ac3_parse_stop);
|
||||||
|
@ -208,7 +204,7 @@ gst_ac3_parse_reset (GstAc3Parse * ac3parse)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_ac3_parse_init (GstAc3Parse * ac3parse, GstAc3ParseClass * klass)
|
gst_ac3_parse_init (GstAc3Parse * ac3parse)
|
||||||
{
|
{
|
||||||
gst_base_parse_set_min_frame_size (GST_BASE_PARSE (ac3parse), 64 * 2);
|
gst_base_parse_set_min_frame_size (GST_BASE_PARSE (ac3parse), 64 * 2);
|
||||||
gst_ac3_parse_reset (ac3parse);
|
gst_ac3_parse_reset (ac3parse);
|
||||||
|
|
|
@ -83,23 +83,21 @@ gboolean gst_amr_parse_check_valid_frame (GstBaseParse * parse,
|
||||||
GstFlowReturn gst_amr_parse_parse_frame (GstBaseParse * parse,
|
GstFlowReturn gst_amr_parse_parse_frame (GstBaseParse * parse,
|
||||||
GstBaseParseFrame * frame);
|
GstBaseParseFrame * frame);
|
||||||
|
|
||||||
#define _do_init(bla) \
|
G_DEFINE_TYPE (GstAmrParse, gst_amr_parse, GST_TYPE_BASE_PARSE);
|
||||||
GST_DEBUG_CATEGORY_INIT (amrparse_debug, "amrparse", 0, \
|
|
||||||
"AMR-NB audio stream parser");
|
|
||||||
|
|
||||||
GST_BOILERPLATE_FULL (GstAmrParse, gst_amr_parse, GstBaseParse,
|
|
||||||
GST_TYPE_BASE_PARSE, _do_init);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_amr_parse_base_init:
|
* gst_amr_parse_class_init:
|
||||||
* @klass: #GstElementClass.
|
* @klass: GstAmrParseClass.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
gst_amr_parse_base_init (gpointer klass)
|
gst_amr_parse_class_init (GstAmrParseClass * klass)
|
||||||
{
|
{
|
||||||
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
|
||||||
|
GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass);
|
||||||
|
|
||||||
|
GST_DEBUG_CATEGORY_INIT (amrparse_debug, "amrparse", 0,
|
||||||
|
"AMR-NB audio stream parser");
|
||||||
|
|
||||||
gst_element_class_add_pad_template (element_class,
|
gst_element_class_add_pad_template (element_class,
|
||||||
gst_static_pad_template_get (&sink_template));
|
gst_static_pad_template_get (&sink_template));
|
||||||
|
@ -110,18 +108,6 @@ gst_amr_parse_base_init (gpointer klass)
|
||||||
"AMR audio stream parser", "Codec/Parser/Audio",
|
"AMR audio stream parser", "Codec/Parser/Audio",
|
||||||
"Adaptive Multi-Rate audio parser",
|
"Adaptive Multi-Rate audio parser",
|
||||||
"Ronald Bultje <rbultje@ronald.bitfreak.net>");
|
"Ronald Bultje <rbultje@ronald.bitfreak.net>");
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gst_amr_parse_class_init:
|
|
||||||
* @klass: GstAmrParseClass.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
gst_amr_parse_class_init (GstAmrParseClass * klass)
|
|
||||||
{
|
|
||||||
GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass);
|
|
||||||
|
|
||||||
parse_class->start = GST_DEBUG_FUNCPTR (gst_amr_parse_start);
|
parse_class->start = GST_DEBUG_FUNCPTR (gst_amr_parse_start);
|
||||||
parse_class->stop = GST_DEBUG_FUNCPTR (gst_amr_parse_stop);
|
parse_class->stop = GST_DEBUG_FUNCPTR (gst_amr_parse_stop);
|
||||||
|
@ -139,7 +125,7 @@ gst_amr_parse_class_init (GstAmrParseClass * klass)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
gst_amr_parse_init (GstAmrParse * amrparse, GstAmrParseClass * klass)
|
gst_amr_parse_init (GstAmrParse * amrparse)
|
||||||
{
|
{
|
||||||
/* init rest */
|
/* init rest */
|
||||||
gst_base_parse_set_min_frame_size (GST_BASE_PARSE (amrparse), 62);
|
gst_base_parse_set_min_frame_size (GST_BASE_PARSE (amrparse), 62);
|
||||||
|
@ -270,14 +256,17 @@ gst_amr_parse_check_valid_frame (GstBaseParse * parse,
|
||||||
GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
|
GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
|
||||||
{
|
{
|
||||||
GstBuffer *buffer;
|
GstBuffer *buffer;
|
||||||
const guint8 *data;
|
guint8 *data;
|
||||||
|
gsize size;
|
||||||
gint fsize, mode, dsize;
|
gint fsize, mode, dsize;
|
||||||
GstAmrParse *amrparse;
|
GstAmrParse *amrparse;
|
||||||
|
gboolean ret = FALSE;
|
||||||
|
|
||||||
amrparse = GST_AMR_PARSE (parse);
|
amrparse = GST_AMR_PARSE (parse);
|
||||||
buffer = frame->buffer;
|
buffer = frame->buffer;
|
||||||
data = GST_BUFFER_DATA (buffer);
|
|
||||||
dsize = GST_BUFFER_SIZE (buffer);
|
data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
|
||||||
|
dsize = size;
|
||||||
|
|
||||||
GST_LOG ("buffer: %d bytes", dsize);
|
GST_LOG ("buffer: %d bytes", dsize);
|
||||||
|
|
||||||
|
@ -291,7 +280,7 @@ gst_amr_parse_check_valid_frame (GstBaseParse * parse,
|
||||||
}
|
}
|
||||||
/* We return FALSE, so this frame won't get pushed forward. Instead,
|
/* We return FALSE, so this frame won't get pushed forward. Instead,
|
||||||
the "skip" value is set, so next time we will receive a valid frame. */
|
the "skip" value is set, so next time we will receive a valid frame. */
|
||||||
return FALSE;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Does this look like a possible frame header candidate? */
|
/* Does this look like a possible frame header candidate? */
|
||||||
|
@ -311,12 +300,16 @@ gst_amr_parse_check_valid_frame (GstBaseParse * parse,
|
||||||
(!GST_BASE_PARSE_LOST_SYNC (parse) || GST_BASE_PARSE_DRAINING (parse)
|
(!GST_BASE_PARSE_LOST_SYNC (parse) || GST_BASE_PARSE_DRAINING (parse)
|
||||||
|| (dsize > fsize && (data[fsize] & 0x83) == 0))) {
|
|| (dsize > fsize && (data[fsize] & 0x83) == 0))) {
|
||||||
*framesize = fsize;
|
*framesize = fsize;
|
||||||
return TRUE;
|
ret = TRUE;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_LOG ("sync lost");
|
GST_LOG ("sync lost");
|
||||||
return FALSE;
|
|
||||||
|
done:
|
||||||
|
gst_buffer_unmap (buffer, data, size);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue