diff options
Diffstat (limited to 'gst/audioparsers/gstamrparse.c')
-rw-r--r-- | gst/audioparsers/gstamrparse.c | 91 |
1 files changed, 72 insertions, 19 deletions
diff --git a/gst/audioparsers/gstamrparse.c b/gst/audioparsers/gstamrparse.c index 8f0dabc..8f6ef94 100644 --- a/gst/audioparsers/gstamrparse.c +++ b/gst/audioparsers/gstamrparse.c @@ -71,16 +71,17 @@ static const gint block_size_wb[16] = #define AMR_FRAME_DURATION (GST_SECOND/AMR_FRAMES_PER_SECOND) #define AMR_MIME_HEADER_SIZE 9 -gboolean gst_amr_parse_start (GstBaseParse * parse); -gboolean gst_amr_parse_stop (GstBaseParse * parse); +static gboolean gst_amr_parse_start (GstBaseParse * parse); +static gboolean gst_amr_parse_stop (GstBaseParse * parse); static gboolean gst_amr_parse_sink_setcaps (GstBaseParse * parse, GstCaps * caps); +static GstCaps *gst_amr_parse_sink_getcaps (GstBaseParse * parse); -gboolean gst_amr_parse_check_valid_frame (GstBaseParse * parse, +static gboolean gst_amr_parse_check_valid_frame (GstBaseParse * parse, GstBaseParseFrame * frame, guint * framesize, gint * skipsize); -GstFlowReturn gst_amr_parse_parse_frame (GstBaseParse * parse, +static GstFlowReturn gst_amr_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame); #define _do_init(bla) \ @@ -90,7 +91,6 @@ GstFlowReturn gst_amr_parse_parse_frame (GstBaseParse * parse, GST_BOILERPLATE_FULL (GstAmrParse, gst_amr_parse, GstBaseParse, GST_TYPE_BASE_PARSE, _do_init); - /** * gst_amr_parse_base_init: * @klass: #GstElementClass. @@ -101,10 +101,9 @@ gst_amr_parse_base_init (gpointer klass) { GstElementClass *element_class = GST_ELEMENT_CLASS (klass); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_template)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&src_template)); + gst_element_class_add_static_pad_template (element_class, + &sink_template); + gst_element_class_add_static_pad_template (element_class, &src_template); gst_element_class_set_details_simple (element_class, "AMR audio stream parser", "Codec/Parser/Audio", @@ -126,6 +125,7 @@ gst_amr_parse_class_init (GstAmrParseClass * klass) parse_class->start = GST_DEBUG_FUNCPTR (gst_amr_parse_start); parse_class->stop = GST_DEBUG_FUNCPTR (gst_amr_parse_stop); parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_amr_parse_sink_setcaps); + parse_class->get_sink_caps = GST_DEBUG_FUNCPTR (gst_amr_parse_sink_getcaps); parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_amr_parse_parse_frame); parse_class->check_valid_frame = GST_DEBUG_FUNCPTR (gst_amr_parse_check_valid_frame); @@ -171,7 +171,7 @@ gst_amr_parse_set_src_caps (GstAmrParse * amrparse) GST_DEBUG_OBJECT (amrparse, "setting srcpad caps to AMR-NB"); /* Max. size of NB frame is 31 bytes, so we can set the min. frame size to 32 (+1 for next frame header) */ - gst_base_parse_set_min_frame_size (GST_BASE_PARSE (amrparse), 33); + gst_base_parse_set_min_frame_size (GST_BASE_PARSE (amrparse), 32); src_caps = gst_caps_new_simple ("audio/AMR", "channels", G_TYPE_INT, 1, "rate", G_TYPE_INT, 8000, NULL); } @@ -265,7 +265,7 @@ gst_amr_parse_parse_header (GstAmrParse * amrparse, * * Returns: TRUE if the given data contains valid frame. */ -gboolean +static gboolean gst_amr_parse_check_valid_frame (GstBaseParse * parse, GstBaseParseFrame * frame, guint * framesize, gint * skipsize) { @@ -307,11 +307,28 @@ gst_amr_parse_check_valid_frame (GstBaseParse * parse, * to contain a valid header as well (and there is enough data to * perform this check) */ - if (fsize && - (!GST_BASE_PARSE_LOST_SYNC (parse) || GST_BASE_PARSE_DRAINING (parse) - || (dsize >= fsize && (data[fsize] & 0x83) == 0))) { - *framesize = fsize; - return TRUE; + if (fsize) { + gboolean found = FALSE; + + /* in sync, no further check */ + if (!GST_BASE_PARSE_LOST_SYNC (parse)) { + found = TRUE; + } else if (dsize > fsize) { + /* enough data, check for next sync */ + if ((data[fsize] & 0x83) == 0) + found = TRUE; + } else if (GST_BASE_PARSE_DRAINING (parse)) { + /* not enough, but draining, so ok */ + found = TRUE; + } else { + /* indicate we need not skip, but need more data */ + *skipsize = 0; + *framesize = fsize + 1; + } + if (found) { + *framesize = fsize; + return TRUE; + } } } @@ -329,7 +346,7 @@ gst_amr_parse_check_valid_frame (GstBaseParse * parse, * * Returns: #GstFlowReturn defining the parsing status. */ -GstFlowReturn +static GstFlowReturn gst_amr_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame) { return GST_FLOW_OK; @@ -344,7 +361,7 @@ gst_amr_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame) * * Returns: TRUE on success. */ -gboolean +static gboolean gst_amr_parse_start (GstBaseParse * parse) { GstAmrParse *amrparse; @@ -365,7 +382,7 @@ gst_amr_parse_start (GstBaseParse * parse) * * Returns: TRUE on success. */ -gboolean +static gboolean gst_amr_parse_stop (GstBaseParse * parse) { GstAmrParse *amrparse; @@ -376,3 +393,39 @@ gst_amr_parse_stop (GstBaseParse * parse) amrparse->header = 0; return TRUE; } + +static GstCaps * +gst_amr_parse_sink_getcaps (GstBaseParse * parse) +{ + GstCaps *peercaps; + GstCaps *res; + + peercaps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (parse)); + if (peercaps) { + guint i, n; + + /* Rename structure names */ + peercaps = gst_caps_make_writable (peercaps); + n = gst_caps_get_size (peercaps); + for (i = 0; i < n; i++) { + GstStructure *s = gst_caps_get_structure (peercaps, i); + + if (gst_structure_has_name (s, "audio/AMR")) + gst_structure_set_name (s, "audio/x-amr-nb-sh"); + else + gst_structure_set_name (s, "audio/x-amr-wb-sh"); + } + + res = + gst_caps_intersect_full (peercaps, + gst_pad_get_pad_template_caps (GST_BASE_PARSE_SRC_PAD (parse)), + GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (peercaps); + } else { + res = + gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD + (parse))); + } + + return res; +} |