From 6a45c4f65ecde09cfd995e3439203a76734561fc Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Mon, 10 Jan 2011 16:56:36 +0100 Subject: [PATCH] baseparse: refactor passthrough into format flags Also add a format flag to signal baseparse that subclass/format can provide (parsed) timestamp rather than an estimated one. In particular, such "strong" timestamp then allows to e.g. determine duration. --- gst/audioparsers/gstaacparse.c | 7 ++--- gst/audioparsers/gstbaseparse.c | 45 +++++++++++++++++++-------------- gst/audioparsers/gstbaseparse.h | 28 +++++++++++++++++--- gst/audioparsers/gstflacparse.c | 3 +++ 4 files changed, 58 insertions(+), 25 deletions(-) diff --git a/gst/audioparsers/gstaacparse.c b/gst/audioparsers/gstaacparse.c index 140f5e4dff..09e3e71f2c 100644 --- a/gst/audioparsers/gstaacparse.c +++ b/gst/audioparsers/gstaacparse.c @@ -267,7 +267,8 @@ gst_aacparse_sink_setcaps (GstBaseParse * parse, GstCaps * caps) /* arrange for metadata and get out of the way */ gst_aacparse_set_src_caps (aacparse, caps); - gst_base_parse_set_passthrough (parse, TRUE); + gst_base_parse_set_format (parse, + GST_BASE_PARSE_FORMAT_PASSTHROUGH, TRUE); } else return FALSE; @@ -542,7 +543,8 @@ gst_aacparse_detect_stream (GstAacParse * aacparse, /* arrange for metadata and get out of the way */ gst_aacparse_set_src_caps (aacparse, GST_PAD_CAPS (GST_BASE_PARSE_SINK_PAD (aacparse))); - gst_base_parse_set_passthrough (GST_BASE_PARSE (aacparse), TRUE); + gst_base_parse_set_format (GST_BASE_PARSE (aacparse), + GST_BASE_PARSE_FORMAT_PASSTHROUGH, TRUE); *framesize = avail; return TRUE; @@ -693,7 +695,6 @@ gst_aacparse_start (GstBaseParse * parse) aacparse = GST_AACPARSE (parse); GST_DEBUG ("start"); gst_base_parse_set_min_frame_size (GST_BASE_PARSE (aacparse), 1024); - gst_base_parse_set_passthrough (parse, FALSE); return TRUE; } diff --git a/gst/audioparsers/gstbaseparse.c b/gst/audioparsers/gstbaseparse.c index 91898466f8..a4505c197b 100644 --- a/gst/audioparsers/gstbaseparse.c +++ b/gst/audioparsers/gstbaseparse.c @@ -158,7 +158,7 @@ * Update the duration information with @gst_base_parse_set_duration * * - * Optionally passthrough using @gst_base_parse_set_passthrough + * Optionally passthrough using @gst_base_parse_set_format * * * Configure various baseparse parameters using @gst_base_parse_set_seek and @@ -220,7 +220,7 @@ struct _GstBaseParsePrivate gint64 estimated_duration; guint min_frame_size; - gboolean passthrough; + guint format; guint fps_num, fps_den; guint update_interval; guint bitrate; @@ -294,6 +294,12 @@ typedef struct _GstBaseParseSeek GstClockTime start_ts; } GstBaseParseSeek; +#define GST_BASE_PARSE_PASSTHROUGH(parse) \ + (parse->priv->format & GST_BASE_PARSE_FORMAT_PASSTHROUGH) +#define GST_BASE_PARSE_HAS_TIME(parse) \ + (parse->priv->format & GST_BASE_PARSE_FORMAT_HAS_TIME) + + static GstElementClass *parent_class = NULL; static void gst_base_parse_class_init (GstBaseParseClass * klass); @@ -571,7 +577,7 @@ gst_base_parse_reset (GstBaseParse * parse) parse->priv->first_frame_offset = -1; parse->priv->estimated_duration = -1; parse->priv->next_ts = 0; - parse->priv->passthrough = FALSE; + parse->priv->format = 0; parse->priv->post_min_bitrate = TRUE; parse->priv->post_avg_bitrate = TRUE; parse->priv->post_max_bitrate = TRUE; @@ -1471,10 +1477,11 @@ gst_base_parse_handle_and_push_frame (GstBaseParse * parse, /* subclass must play nice */ g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR); - /* check initial frame to determine if subclass/format can provide ts. + /* check if subclass/format can provide ts. * If so, that allows and enables extra seek and duration determining options */ if (G_UNLIKELY (parse->priv->first_frame_offset < 0 && ret == GST_FLOW_OK)) { if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) && + GST_BASE_PARSE_HAS_TIME (parse) && parse->priv->pad_mode == GST_ACTIVATE_PULL) { parse->priv->first_frame_offset = offset; parse->priv->first_frame_ts = GST_BUFFER_TIMESTAMP (buffer); @@ -1583,7 +1590,7 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame) g_return_val_if_fail (GST_PAD_CAPS (parse->srcpad), GST_FLOW_ERROR); /* segment adjustment magic; only if we are running the whole show */ - if (!parse->priv->passthrough && parse->segment.rate > 0.0 && + if (!GST_BASE_PARSE_PASSTHROUGH (parse) && parse->segment.rate > 0.0 && (parse->priv->pad_mode == GST_ACTIVATE_PULL || parse->priv->upstream_seekable)) { /* segment times are typically estimates, @@ -1748,7 +1755,7 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame) GST_BUFFER_SIZE (buffer), gst_flow_get_name (ret)); /* if we are not sufficiently in control, let upstream decide on EOS */ if (ret == GST_FLOW_UNEXPECTED && - (parse->priv->passthrough || + (GST_BASE_PARSE_PASSTHROUGH (parse) || (parse->priv->pad_mode == GST_ACTIVATE_PUSH && !parse->priv->upstream_seekable))) ret = GST_FLOW_OK; @@ -1957,7 +1964,7 @@ gst_base_parse_chain (GstPad * pad, GstBuffer * buffer) if (G_LIKELY (buffer)) { GST_LOG_OBJECT (parse, "buffer size: %d, offset = %" G_GINT64_FORMAT, GST_BUFFER_SIZE (buffer), GST_BUFFER_OFFSET (buffer)); - if (G_UNLIKELY (parse->priv->passthrough)) { + if (G_UNLIKELY (GST_BASE_PARSE_PASSTHROUGH (parse))) { frame->buffer = gst_buffer_make_metadata_writable (buffer); return gst_base_parse_push_frame (parse, frame); } @@ -2722,24 +2729,24 @@ gst_base_parse_set_min_frame_size (GstBaseParse * parse, guint min_size) } /** - * gst_base_parse_set_passthrough: - * @parse: the #GstBaseParse to set - * @passthrough: boolean indicating passthrough mode. + * gst_base_parse_set_format: + * @parse: the #GstBaseParseFormat to set or unset + * @flags: format flag to enable or disable + * @on: whether or not to enable * - * Set passthrough mode for this parser (which only applies operating in pull - * mode). If operating in passthrough, incoming buffers are pushed through - * unmodified. That is, no @check_valid_frame or @parse_frame callbacks - * will be invoked. On the ohter hand, @pre_push_buffer is still invoked, - * where subclass can perform as much or as little is appropriate for - * "passthrough" semantics. + * Set flags describing characteristics of parsed format. */ void -gst_base_parse_set_passthrough (GstBaseParse * parse, gboolean passthrough) +gst_base_parse_set_format (GstBaseParse * parse, GstBaseParseFormat flag, + gboolean on) { g_return_if_fail (parse != NULL); - parse->priv->passthrough = passthrough; - GST_LOG_OBJECT (parse, "set passthrough: %d", passthrough); + GST_LOG_OBJECT (parse, "set flag %d to %d", flag, on); + if (on) + parse->priv->format |= flag; + else + parse->priv->format &= ~flag; } /** diff --git a/gst/audioparsers/gstbaseparse.h b/gst/audioparsers/gstbaseparse.h index d5d4415a18..0438c42134 100644 --- a/gst/audioparsers/gstbaseparse.h +++ b/gst/audioparsers/gstbaseparse.h @@ -163,12 +163,33 @@ typedef struct { */ #define GST_BASE_PARSE_FRAME_DRAIN(frame) (!!(frame->flags & GST_BASE_PARSE_FRAME_FLAG_DRAIN)) +/** + * GstBaseParseFormat: + * @GST_BASE_PARSE_FORMAT_NONE: default setting + * @GST_BASE_PARSE_FORMAT_PASSTHROUGH: nature of format or configuration + * does not allow (much) parsing, so parser should operate in passthrough mode + * (which only applies operating in pull mode). That is, incoming buffers + * are pushed through unmodified, i.e. no @check_valid_frame or @parse_frame + * callbacks will be invoked. On the other hand, @pre_push_buffer is still invoked, + * where subclass can perform as much or as little is appropriate for + * "passthrough" semantics. + * @GST_BASE_PARSE_FORMAT_HAS_TIME: frames carry timing info which subclass + * can (generally) parse and provide. In particular, intrinsic time + * (rather than estimated) can be obtained following seek. + * + * Since: 0.10.x + */ +typedef enum _GstBaseParseFormat { + GST_BASE_PARSE_FORMAT_NONE = 0, + GST_BASE_PARSE_FORMAT_PASSTHROUGH = (1 << 0), + GST_BASE_PARSE_FORMAT_HAS_TIME = (1 << 1), +} GstBaseParseFormat; /** * GstBaseParseSeekable: * @GST_BASE_PARSE_SEEK_NONE: No seeking possible. - * GST_BASE_PARSE_SEEK_DEFAULT: Default seeking possible using estimated bitrate. - * GST_BASE_PARSE_SEEK_TABLE: Additional metadata provides more accurate seeking. + * @GST_BASE_PARSE_SEEK_DEFAULT: Default seeking possible using estimated bitrate. + * @GST_BASE_PARSE_SEEK_TABLE: Additional metadata provides more accurate seeking. * * Indicates what level (of quality) of seeking is possible. * @@ -317,7 +338,8 @@ void gst_base_parse_set_seek (GstBaseParse * parse, void gst_base_parse_set_min_frame_size (GstBaseParse *parse, guint min_size); -void gst_base_parse_set_passthrough (GstBaseParse * parse, gboolean passthrough); +void gst_base_parse_set_format (GstBaseParse * parse, GstBaseParseFormat flag, + gboolean on); void gst_base_parse_set_frame_props (GstBaseParse * parse, guint fps_num, guint fps_den, guint lead_in, guint lead_out); diff --git a/gst/audioparsers/gstflacparse.c b/gst/audioparsers/gstflacparse.c index f991095f81..8306e8e8b1 100644 --- a/gst/audioparsers/gstflacparse.c +++ b/gst/audioparsers/gstflacparse.c @@ -326,6 +326,9 @@ gst_flac_parse_start (GstBaseParse * parse) /* "fLaC" marker */ gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), 4); + /* inform baseclass we can come up with ts, based on counters in packets */ + gst_base_parse_set_format (GST_BASE_PARSE (flacparse), + GST_BASE_PARSE_FORMAT_HAS_TIME, TRUE); return TRUE; }