337
337
gboolean detecting;
338
338
GList *detect_buffers;
339
339
guint detect_buffers_size;
341
/* if TRUE, a STREAM_START event needs to be pushed */
342
gboolean push_stream_start;
342
345
typedef struct _GstBaseParseSeek
635
638
* sure gst_base_parse_frame_free() only frees the contents but not
636
639
* the actual frame. Use this function to initialise a #GstBaseParseFrame
637
640
* allocated on the stack.
642
643
gst_base_parse_frame_init (GstBaseParseFrame * frame)
1407
1404
parse->priv->max_bitrate);
1409
1406
if (taglist != NULL) {
1410
gst_pad_push_event (parse->srcpad, gst_event_new_tag ("GstParser",
1407
gst_pad_push_event (parse->srcpad, gst_event_new_tag (taglist));
1844
1838
g_return_val_if_fail (frame != NULL, GST_FLOW_ERROR);
1846
/* some one-time start-up */
1847
if (G_UNLIKELY (!parse->priv->framecount)) {
1848
gst_base_parse_check_seekability (parse);
1849
gst_base_parse_check_upstream (parse);
1852
1840
buffer = frame->buffer;
1853
1841
offset = frame->offset;
2157
2141
GST_LOG_OBJECT (parse, "finished frame at offset %" G_GUINT64_FORMAT ", "
2158
2142
"flushing size %d", frame->offset, size);
2144
/* some one-time start-up */
2145
if (G_UNLIKELY (parse->priv->framecount == 0)) {
2146
gst_base_parse_check_seekability (parse);
2147
gst_base_parse_check_upstream (parse);
2150
parse->priv->flushed += size;
2160
2152
if (parse->priv->scanning && frame->buffer) {
2161
2153
if (!parse->priv->scanned_frame) {
2162
2154
parse->priv->scanned_frame = gst_base_parse_frame_copy (frame);
2758
2748
* pull and scan for next frame starting from current offset
2759
2749
* ajusts sync, drain and offset going along */
2760
2750
static GstFlowReturn
2761
gst_base_parse_scan_frame (GstBaseParse * parse, GstBaseParseClass * klass,
2751
gst_base_parse_scan_frame (GstBaseParse * parse, GstBaseParseClass * klass)
2764
2753
GstBuffer *buffer;
2765
2754
GstFlowReturn ret = GST_FLOW_OK;
2858
2847
parse = GST_BASE_PARSE (gst_pad_get_parent (pad));
2859
2848
klass = GST_BASE_PARSE_GET_CLASS (parse);
2850
GST_DEBUG_OBJECT (parse, "hello");
2852
if (G_UNLIKELY (parse->priv->push_stream_start)) {
2856
gst_pad_create_stream_id (parse->srcpad, GST_ELEMENT_CAST (parse),
2859
GST_DEBUG_OBJECT (parse, "Pushing STREAM_START");
2860
gst_pad_push_event (parse->srcpad, gst_event_new_stream_start (stream_id));
2861
parse->priv->push_stream_start = FALSE;
2861
2865
/* reverse playback:
2862
2866
* first fragment (closest to stop time) is handled normally below,
2863
2867
* then we pull in fragments going backwards */
2912
2916
if (ret == GST_FLOW_EOS) {
2913
2917
/* handle end-of-stream/segment */
2914
if (parse->segment.flags & GST_SEEK_FLAG_SEGMENT) {
2918
if (parse->segment.flags & GST_SEGMENT_FLAG_SEGMENT) {
2917
2921
if ((stop = parse->segment.stop) == -1)
2923
2927
(GST_ELEMENT_CAST (parse),
2924
2928
gst_message_new_segment_done (GST_OBJECT_CAST (parse),
2925
2929
GST_FORMAT_TIME, stop));
2930
gst_pad_push_event (parse->srcpad,
2931
gst_event_new_segment_done (GST_FORMAT_TIME, stop));
2927
2933
/* If we STILL have zero frames processed, fire an error */
2928
2934
if (parse->priv->framecount == 0) {
2985
2991
if (!gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE))
2986
2992
goto baseparse_push;
2994
parse->priv->push_stream_start = TRUE;
2988
2996
return gst_pad_start_task (sinkpad, (GstTaskFunction) gst_base_parse_loop,
2991
2999
baseparse_push:
3084
3092
* duration. Alternatively, if @interval is non-zero (default), then stream
3085
3093
* duration is determined based on estimated bitrate, and updated every @interval
3091
3097
gst_base_parse_set_duration (GstBaseParse * parse,
3133
3139
* is used to estimate the total duration of the stream and to estimate
3134
3140
* a seek position, if there's no index and the format is syncable
3135
3141
* (see gst_base_parse_set_syncable()).
3140
3144
gst_base_parse_set_average_bitrate (GstBaseParse * parse, guint bitrate)
3176
3178
* location, a corresponding decoder might need an initial @lead_in and a
3177
3179
* following @lead_out number of frames to ensure the desired segment is
3178
3180
* entirely filled upon decoding.
3183
3183
gst_base_parse_set_frame_rate (GstBaseParse * parse, guint fps_num,
3226
3226
* Set if frames carry timing information which the subclass can (generally)
3227
3227
* parse and provide. In particular, intrinsic (rather than estimated) time
3228
3228
* can be obtained following a seek.
3233
3231
gst_base_parse_set_has_timing_info (GstBaseParse * parse, gboolean has_timing)
3244
3242
* Set if frame starts can be identified. This is set by default and
3245
3243
* determines whether seeking based on bitrate averages
3246
3244
* is possible for a format/stream.
3251
3247
gst_base_parse_set_syncable (GstBaseParse * parse, gboolean syncable)
3266
3262
* callbacks will be invoked, but @pre_push_frame will still be invoked,
3267
3263
* so subclass can perform as much or as little is appropriate for
3268
3264
* passthrough semantics in @pre_push_frame.
3273
3267
gst_base_parse_set_passthrough (GstBaseParse * parse, gboolean passthrough)
3285
3279
* Sets the minimum and maximum (which may likely be equal) latency introduced
3286
3280
* by the parsing process. If there is such a latency, which depends on the
3287
3281
* particular parsing of the format, it typically corresponds to 1 frame duration.
3292
3284
gst_base_parse_set_latency (GstBaseParse * parse, GstClockTime min_latency,
3514
3506
parse->priv->offset = *pos;
3515
3507
/* mark as scanning so frames don't get processed all the way */
3516
3508
parse->priv->scanning = TRUE;
3517
ret = gst_base_parse_scan_frame (parse, klass, FALSE);
3509
ret = gst_base_parse_scan_frame (parse, klass);
3518
3510
parse->priv->scanning = FALSE;
3519
3511
/* retrieve frame found during scan */
3520
3512
sframe = parse->priv->scanned_frame;
3750
3742
GstFormat format;
3751
3743
GstSeekFlags flags;
3752
GstSeekType cur_type = GST_SEEK_TYPE_NONE, stop_type;
3744
GstSeekType start_type = GST_SEEK_TYPE_NONE, stop_type;
3753
3745
gboolean flush, update, res = TRUE, accurate;
3754
gint64 cur, stop, seekpos, seekstop;
3746
gint64 start, stop, seekpos, seekstop;
3755
3747
GstSegment seeksegment = { 0, };
3756
3748
GstClockTime start_ts;
3758
3750
gst_event_parse_seek (event, &rate, &format, &flags,
3759
&cur_type, &cur, &stop_type, &stop);
3751
&start_type, &start, &stop_type, &stop);
3761
3753
GST_DEBUG_OBJECT (parse, "seek to format %s, rate %f, "
3762
3754
"start type %d at %" GST_TIME_FORMAT ", end type %d at %"
3763
3755
GST_TIME_FORMAT, gst_format_get_name (format), rate,
3764
cur_type, GST_TIME_ARGS (cur), stop_type, GST_TIME_ARGS (stop));
3756
start_type, GST_TIME_ARGS (start), stop_type, GST_TIME_ARGS (stop));
3766
3758
/* no negative rates in push mode */
3767
3759
if (rate < 0.0 && parse->priv->pad_mode == GST_PAD_MODE_PUSH)
3768
3760
goto negative_rate;
3770
if (cur_type != GST_SEEK_TYPE_SET ||
3771
(stop_type != GST_SEEK_TYPE_SET && stop_type != GST_SEEK_TYPE_NONE))
3774
3762
/* For any format other than TIME, see if upstream handles
3775
3763
* it directly or fail. For TIME, try upstream, but do it ourselves if
3776
3764
* it fails upstream */
3788
3780
GST_DEBUG_OBJECT (parse, "configuring seek");
3789
3781
gst_segment_do_seek (&seeksegment, rate, format, flags,
3790
cur_type, cur, stop_type, stop, &update);
3782
start_type, start, stop_type, stop, &update);
3792
3784
/* accurate seeking implies seek tables are used to obtain position,
3793
3785
* and the requested segment is maintained exactly, not adjusted any way */
3917
3909
/* Start streaming thread if paused */
3918
3910
gst_pad_start_task (parse->sinkpad,
3919
(GstTaskFunction) gst_base_parse_loop, parse->sinkpad);
3911
(GstTaskFunction) gst_base_parse_loop, parse->sinkpad, NULL);
3921
3913
GST_PAD_STREAM_UNLOCK (parse->sinkpad);
3998
3990
gst_event_parse_tag (event, &taglist);
3992
/* We only care about stream tags here */
3993
if (gst_tag_list_get_scope (taglist) != GST_TAG_SCOPE_STREAM)
4000
3996
if (gst_tag_list_get_uint (taglist, GST_TAG_MINIMUM_BITRATE, &tmp)) {
4001
3997
GST_DEBUG_OBJECT (parse, "upstream min bitrate %d", tmp);
4002
3998
parse->priv->post_min_bitrate = FALSE;