summaryrefslogtreecommitdiff
path: root/gst/audioparsers/gstamrparse.c
diff options
context:
space:
mode:
Diffstat (limited to 'gst/audioparsers/gstamrparse.c')
-rw-r--r--gst/audioparsers/gstamrparse.c91
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;
+}