423
428
static GstFlowReturn gst_base_parse_parse_frame (GstBaseParse * parse,
424
429
GstBaseParseFrame * frame);
426
static gboolean gst_base_parse_sink_eventfunc (GstBaseParse * parse,
431
static gboolean gst_base_parse_sink_default (GstBaseParse * parse,
427
432
GstEvent * event);
429
static gboolean gst_base_parse_src_eventfunc (GstBaseParse * parse,
434
static gboolean gst_base_parse_src_default (GstBaseParse * parse,
430
435
GstEvent * event);
432
437
static void gst_base_parse_drain (GstBaseParse * parse);
533
538
/* Default handlers */
534
klass->sink_event = gst_base_parse_sink_eventfunc;
535
klass->src_event = gst_base_parse_src_eventfunc;
539
klass->sink_event = gst_base_parse_sink_default;
540
klass->src_event = gst_base_parse_src_default;
536
541
klass->convert = gst_base_parse_convert_default;
538
543
GST_DEBUG_CATEGORY_INIT (gst_base_parse_debug, "baseparse", 0,
712
717
parse->priv->framecount = 0;
713
718
parse->priv->bytecount = 0;
714
719
parse->priv->acc_duration = 0;
715
parse->priv->first_frame_ts = GST_CLOCK_TIME_NONE;
720
parse->priv->first_frame_pts = GST_CLOCK_TIME_NONE;
721
parse->priv->first_frame_dts = GST_CLOCK_TIME_NONE;
716
722
parse->priv->first_frame_offset = -1;
717
723
parse->priv->estimated_duration = -1;
718
724
parse->priv->estimated_drift = 0;
719
parse->priv->next_ts = 0;
725
parse->priv->next_pts = 0;
726
parse->priv->next_dts = 0;
720
727
parse->priv->syncable = TRUE;
721
728
parse->priv->passthrough = FALSE;
729
parse->priv->pts_interpolate = TRUE;
722
730
parse->priv->has_timing_info = FALSE;
723
731
parse->priv->post_min_bitrate = TRUE;
724
732
parse->priv->post_avg_bitrate = TRUE;
738
746
parse->priv->exact_position = TRUE;
739
747
parse->priv->seen_keyframe = FALSE;
741
parse->priv->last_ts = GST_CLOCK_TIME_NONE;
749
parse->priv->last_dts = GST_CLOCK_TIME_NONE;
750
parse->priv->last_pts = GST_CLOCK_TIME_NONE;
742
751
parse->priv->last_offset = 0;
744
753
g_list_foreach (parse->priv->pending_events, (GFunc) gst_mini_object_unref,
780
789
GstBuffer *buffer = frame->buffer;
782
if (!GST_BUFFER_TIMESTAMP_IS_VALID (buffer) &&
783
GST_CLOCK_TIME_IS_VALID (parse->priv->next_ts)) {
784
GST_BUFFER_TIMESTAMP (buffer) = parse->priv->next_ts;
791
if (!GST_BUFFER_PTS_IS_VALID (buffer) &&
792
GST_CLOCK_TIME_IS_VALID (parse->priv->next_pts)) {
793
GST_BUFFER_PTS (buffer) = parse->priv->next_pts;
795
if (!GST_BUFFER_DTS_IS_VALID (buffer) &&
796
GST_CLOCK_TIME_IS_VALID (parse->priv->next_dts)) {
797
GST_BUFFER_DTS (buffer) = parse->priv->next_dts;
786
799
if (!GST_BUFFER_DURATION_IS_VALID (buffer) &&
787
800
GST_CLOCK_TIME_IS_VALID (parse->priv->frame_duration)) {
856
869
gst_base_parse_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
859
GstBaseParseClass *bclass;
871
GstBaseParse *parse = GST_BASE_PARSE (parent);
872
GstBaseParseClass *bclass = GST_BASE_PARSE_GET_CLASS (parse);
862
parse = GST_BASE_PARSE (parent);
863
bclass = GST_BASE_PARSE_GET_CLASS (parse);
865
GST_DEBUG_OBJECT (parse, "handling event %d, %s", GST_EVENT_TYPE (event),
866
GST_EVENT_TYPE_NAME (event));
868
/* Cache all serialized events except EOS, SEGMENT and FLUSH_STOP if we have a
870
if (parse->priv->pending_segment && GST_EVENT_IS_SERIALIZED (event)
871
&& GST_EVENT_TYPE (event) != GST_EVENT_EOS
872
&& GST_EVENT_TYPE (event) != GST_EVENT_SEGMENT
873
&& GST_EVENT_TYPE (event) != GST_EVENT_FLUSH_START
874
&& GST_EVENT_TYPE (event) != GST_EVENT_FLUSH_STOP
875
&& GST_EVENT_TYPE (event) != GST_EVENT_CAPS) {
877
if (GST_EVENT_TYPE (event) == GST_EVENT_TAG)
878
/* See if any bitrate tags were posted */
879
gst_base_parse_handle_tag (parse, event);
881
parse->priv->pending_events =
882
g_list_append (parse->priv->pending_events, event);
885
if (GST_EVENT_TYPE (event) == GST_EVENT_EOS &&
886
parse->priv->framecount < MIN_FRAMES_TO_POST_BITRATE)
887
/* We've not posted bitrate tags yet - do so now */
888
gst_base_parse_post_bitrates (parse, TRUE, TRUE, TRUE);
890
if (bclass->sink_event)
891
ret = bclass->sink_event (parse, event);
893
gst_event_unref (event);
898
GST_DEBUG_OBJECT (parse, "event handled");
875
ret = bclass->sink_event (parse, event);
904
/* gst_base_parse_sink_eventfunc:
881
/* gst_base_parse_sink_default:
905
882
* @parse: #GstBaseParse.
906
883
* @event: #GstEvent to be handled.
913
890
* Returns: %TRUE if the event was handled and not need forwarding.
916
gst_base_parse_sink_eventfunc (GstBaseParse * parse, GstEvent * event)
893
gst_base_parse_sink_default (GstBaseParse * parse, GstEvent * event)
895
GstBaseParseClass *klass = GST_BASE_PARSE_GET_CLASS (parse);
896
gboolean ret = FALSE;
897
gboolean forward_immediate = FALSE;
899
GST_DEBUG_OBJECT (parse, "handling event %d, %s", GST_EVENT_TYPE (event),
900
GST_EVENT_TYPE_NAME (event));
920
902
switch (GST_EVENT_TYPE (event)) {
921
903
case GST_EVENT_CAPS:
924
GstBaseParseClass *klass;
926
klass = GST_BASE_PARSE_GET_CLASS (parse);
928
907
gst_event_parse_caps (event, &caps);
929
908
GST_DEBUG_OBJECT (parse, "caps: %" GST_PTR_FORMAT, caps);
936
915
/* will send our own caps downstream */
937
916
gst_event_unref (event);
940
920
case GST_EVENT_SEGMENT:
942
922
const GstSegment *in_segment;
943
923
GstSegment out_segment;
944
gint64 offset = 0, next_ts;
947
gdouble rate, applied_rate;
949
gint64 start, stop, pos, next_ts;
924
gint64 offset = 0, next_pts;
953
926
gst_event_parse_segment (event, &in_segment);
954
927
gst_segment_init (&out_segment, GST_FORMAT_TIME);
992
965
/* as these are only estimates, stop is kept open-ended to avoid
993
966
* premature cutting */
994
967
gst_base_parse_convert (parse, GST_FORMAT_BYTES, in_segment->start,
995
GST_FORMAT_TIME, (gint64 *) & next_ts);
968
GST_FORMAT_TIME, (gint64 *) & next_pts);
997
out_segment.start = next_ts;
970
out_segment.start = next_pts;
998
971
out_segment.stop = GST_CLOCK_TIME_NONE;
999
out_segment.time = next_ts;
972
out_segment.time = next_pts;
1001
974
parse->priv->exact_position = (in_segment->start == 0);
1020
993
event = gst_event_new_segment (&out_segment);
1024
997
/* not considered BYTE seekable if it is talking to us in TIME,
1025
998
* whatever else it might claim */
1026
999
parse->priv->upstream_seekable = FALSE;
1027
next_ts = in_segment->start;
1000
next_pts = in_segment->start;
1030
1003
memcpy (&parse->segment, &out_segment, sizeof (GstSegment));
1053
1024
parse->priv->offset = offset;
1054
1025
parse->priv->sync_offset = offset;
1055
parse->priv->next_ts = next_ts;
1056
parse->priv->last_ts = GST_CLOCK_TIME_NONE;
1026
parse->priv->next_pts = next_pts;
1027
parse->priv->last_pts = GST_CLOCK_TIME_NONE;
1028
parse->priv->last_dts = GST_CLOCK_TIME_NONE;
1057
1029
parse->priv->discont = TRUE;
1058
1030
parse->priv->seen_keyframe = FALSE;
1062
1034
case GST_EVENT_FLUSH_START:
1035
GST_OBJECT_LOCK (parse);
1063
1036
parse->priv->flushing = TRUE;
1064
ret = gst_pad_push_event (parse->srcpad, event);
1065
/* Wait for _chain() to exit by taking the srcpad STREAM_LOCK */
1066
GST_PAD_STREAM_LOCK (parse->srcpad);
1067
GST_PAD_STREAM_UNLOCK (parse->srcpad);
1037
GST_OBJECT_UNLOCK (parse);
1070
1040
case GST_EVENT_FLUSH_STOP:
1071
ret = gst_pad_push_event (parse->srcpad, event);
1072
1041
gst_adapter_clear (parse->priv->adapter);
1073
1042
gst_base_parse_clear_queues (parse);
1074
1043
parse->priv->flushing = FALSE;
1075
1044
parse->priv->discont = TRUE;
1076
parse->priv->last_ts = GST_CLOCK_TIME_NONE;
1045
parse->priv->last_pts = GST_CLOCK_TIME_NONE;
1046
parse->priv->last_dts = GST_CLOCK_TIME_NONE;
1077
1047
parse->priv->new_frame = TRUE;
1049
forward_immediate = TRUE;
1080
1052
case GST_EVENT_EOS:
1099
1071
parse->priv->pending_events = NULL;
1100
1072
parse->priv->pending_segment = FALSE;
1074
if (parse->priv->framecount < MIN_FRAMES_TO_POST_BITRATE) {
1075
/* We've not posted bitrate tags yet - do so now */
1076
gst_base_parse_post_bitrates (parse, TRUE, TRUE, TRUE);
1078
forward_immediate = TRUE;
1080
case GST_EVENT_CUSTOM_DOWNSTREAM:{
1081
/* FIXME: Code duplicated from libgstvideo because core can't depend on -base */
1082
#ifndef GST_VIDEO_EVENT_STILL_STATE_NAME
1083
#define GST_VIDEO_EVENT_STILL_STATE_NAME "GstEventStillFrame"
1086
const GstStructure *s;
1087
gboolean ev_still_state;
1089
s = gst_event_get_structure (event);
1091
gst_structure_has_name (s, GST_VIDEO_EVENT_STILL_STATE_NAME) &&
1092
gst_structure_get_boolean (s, "still-state", &ev_still_state)) {
1093
if (ev_still_state) {
1094
GST_DEBUG_OBJECT (parse, "draining current data for still-frame");
1095
if (parse->segment.rate > 0.0)
1096
gst_base_parse_drain (parse);
1098
gst_base_parse_finish_fragment (parse, TRUE);
1100
forward_immediate = TRUE;
1106
GST_DEBUG_OBJECT (parse, "draining current data due to gap event");
1107
if (parse->segment.rate > 0.0)
1108
gst_base_parse_drain (parse);
1110
gst_base_parse_finish_fragment (parse, TRUE);
1111
forward_immediate = TRUE;
1115
/* See if any bitrate tags were posted */
1116
gst_base_parse_handle_tag (parse, event);
1122
/* Forward non-serialized events and EOS/FLUSH_STOP immediately.
1123
* For EOS this is required because no buffer or serialized event
1124
* will come after EOS and nothing could trigger another
1125
* _finish_frame() call. *
1126
* If the subclass handles sending of EOS manually it can return
1127
* _DROPPED from ::finish() and all other subclasses should have
1128
* decoded/flushed all remaining data before this
1130
* For FLUSH_STOP this is required because it is expected
1131
* to be forwarded immediately and no buffers are queued anyway.
1134
if (!GST_EVENT_IS_SERIALIZED (event) || forward_immediate) {
1102
1135
ret = gst_pad_push_event (parse->srcpad, event);
1107
gst_pad_event_default (parse->sinkpad, GST_OBJECT_CAST (parse),
1137
// GST_VIDEO_DECODER_STREAM_LOCK (decoder);
1138
parse->priv->pending_events =
1139
g_list_prepend (parse->priv->pending_events, event);
1140
// GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
1145
GST_DEBUG_OBJECT (parse, "event handled");
1356
1392
if (parse->priv->estimated_drift > GST_SECOND ||
1357
1393
parse->priv->estimated_drift < -GST_SECOND) {
1358
1394
gst_element_post_message (GST_ELEMENT (parse),
1359
gst_message_new_duration (GST_OBJECT (parse),
1360
GST_FORMAT_TIME, dest_value));
1395
gst_message_new_duration_changed (GST_OBJECT (parse)));
1361
1396
parse->priv->estimated_drift = 0;
1363
1398
parse->priv->estimated_duration = dest_value;
1786
1821
/* reverse playback, and no frames found yet, so we are skipping
1787
1822
* the leading part of a fragment, which may form the tail of
1788
1823
* fragment coming later, hopefully subclass skips efficiently ... */
1789
timestamp = gst_adapter_prev_timestamp (parse->priv->adapter, NULL);
1824
pts = gst_adapter_prev_pts (parse->priv->adapter, NULL);
1825
dts = gst_adapter_prev_dts (parse->priv->adapter, NULL);
1790
1826
outbuf = gst_adapter_take_buffer (parse->priv->adapter, *skip);
1791
1827
outbuf = gst_buffer_make_writable (outbuf);
1792
GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
1828
GST_BUFFER_PTS (outbuf) = pts;
1829
GST_BUFFER_DTS (outbuf) = dts;
1793
1830
parse->priv->buffers_head =
1794
1831
g_slist_prepend (parse->priv->buffers_head, outbuf);
1843
1880
/* check if subclass/format can provide ts.
1844
1881
* If so, that allows and enables extra seek and duration determining options */
1845
1882
if (G_UNLIKELY (parse->priv->first_frame_offset < 0)) {
1846
if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) && parse->priv->has_timing_info
1883
if (GST_BUFFER_PTS_IS_VALID (buffer) && parse->priv->has_timing_info
1847
1884
&& parse->priv->pad_mode == GST_PAD_MODE_PULL) {
1848
1885
parse->priv->first_frame_offset = offset;
1849
parse->priv->first_frame_ts = GST_BUFFER_TIMESTAMP (buffer);
1886
parse->priv->first_frame_pts = GST_BUFFER_PTS (buffer);
1887
parse->priv->first_frame_dts = GST_BUFFER_DTS (buffer);
1850
1888
GST_DEBUG_OBJECT (parse, "subclass provided ts %" GST_TIME_FORMAT
1851
1889
" for first frame at offset %" G_GINT64_FORMAT,
1852
GST_TIME_ARGS (parse->priv->first_frame_ts),
1890
GST_TIME_ARGS (parse->priv->first_frame_pts),
1853
1891
parse->priv->first_frame_offset);
1854
1892
if (!GST_CLOCK_TIME_IS_VALID (parse->priv->duration)) {
1869
1907
/* again use default handler to add missing metadata;
1870
1908
* we may have new information on frame properties */
1871
1909
gst_base_parse_parse_frame (parse, frame);
1872
if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) &&
1873
GST_BUFFER_DURATION_IS_VALID (buffer)) {
1874
parse->priv->next_ts =
1875
GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer);
1911
parse->priv->next_pts = GST_CLOCK_TIME_NONE;
1912
if (GST_BUFFER_DTS_IS_VALID (buffer) && GST_BUFFER_DURATION_IS_VALID (buffer)) {
1913
parse->priv->next_dts =
1914
GST_BUFFER_DTS (buffer) + GST_BUFFER_DURATION (buffer);
1915
if (parse->priv->pts_interpolate && GST_BUFFER_PTS_IS_VALID (buffer)) {
1916
GstClockTime next_pts =
1917
GST_BUFFER_PTS (buffer) + GST_BUFFER_DURATION (buffer);
1918
if (next_pts >= parse->priv->next_dts)
1919
parse->priv->next_pts = next_pts;
1877
1922
/* we lost track, do not produce bogus time next time around
1878
1923
* (probably means parser subclass has given up on parsing as well) */
1879
1924
GST_DEBUG_OBJECT (parse, "no next fallback timestamp");
1880
parse->priv->next_ts = GST_CLOCK_TIME_NONE;
1925
parse->priv->next_dts = GST_CLOCK_TIME_NONE;
1883
1928
if (parse->priv->upstream_seekable && parse->priv->exact_position &&
1884
GST_BUFFER_TIMESTAMP_IS_VALID (buffer))
1929
GST_BUFFER_PTS_IS_VALID (buffer))
1885
1930
gst_base_parse_add_index_entry (parse, offset,
1886
GST_BUFFER_TIMESTAMP (buffer),
1931
GST_BUFFER_PTS (buffer),
1887
1932
!GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT), FALSE);
1889
1934
/* All OK, push queued frames if there are any */
1967
2012
/* Push pending events, including NEWSEGMENT events */
1968
2013
if (G_UNLIKELY (parse->priv->pending_events)) {
2014
GList *r = g_list_reverse (parse->priv->pending_events);
1971
for (l = parse->priv->pending_events; l != NULL; l = l->next) {
2017
parse->priv->pending_events = NULL;
2018
for (l = r; l != NULL; l = l->next) {
1972
2019
gst_pad_push_event (parse->srcpad, GST_EVENT (l->data));
1974
g_list_free (parse->priv->pending_events);
1975
parse->priv->pending_events = NULL;
1976
2022
parse->priv->pending_segment = FALSE;
2291
2337
/* invalidate so no fall-back timestamping is performed;
2292
2338
* ok if taken from subclass or upstream */
2293
parse->priv->next_ts = GST_CLOCK_TIME_NONE;
2294
parse->priv->prev_ts = GST_CLOCK_TIME_NONE;
2339
parse->priv->next_pts = GST_CLOCK_TIME_NONE;
2340
parse->priv->prev_pts = GST_CLOCK_TIME_NONE;
2341
parse->priv->next_dts = GST_CLOCK_TIME_NONE;
2342
parse->priv->prev_dts = GST_CLOCK_TIME_NONE;
2295
2343
/* prevent it hanging around stop all the time */
2296
2344
parse->segment.position = GST_CLOCK_TIME_NONE;
2297
2345
/* mark next run */
2351
2399
/* add metadata (if needed to queued buffers */
2352
2400
GST_LOG_OBJECT (parse, "last timestamp: %" GST_TIME_FORMAT,
2353
GST_TIME_ARGS (parse->priv->last_ts));
2401
GST_TIME_ARGS (parse->priv->last_pts));
2354
2402
while (parse->priv->buffers_queued) {
2355
2403
buf = GST_BUFFER_CAST (parse->priv->buffers_queued->data);
2357
2405
/* no touching if upstream or parsing provided time */
2358
if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
2406
if (GST_BUFFER_PTS_IS_VALID (buf)) {
2359
2407
GST_LOG_OBJECT (parse, "buffer has time %" GST_TIME_FORMAT,
2360
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
2361
} else if (GST_CLOCK_TIME_IS_VALID (parse->priv->last_ts) &&
2362
GST_BUFFER_DURATION_IS_VALID (buf)) {
2363
if (G_LIKELY (GST_BUFFER_DURATION (buf) <= parse->priv->last_ts))
2364
parse->priv->last_ts -= GST_BUFFER_DURATION (buf);
2366
parse->priv->last_ts = 0;
2367
GST_BUFFER_TIMESTAMP (buf) = parse->priv->last_ts;
2368
GST_LOG_OBJECT (parse, "applied time %" GST_TIME_FORMAT,
2369
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
2408
GST_TIME_ARGS (GST_BUFFER_PTS (buf)));
2409
} else if (GST_BUFFER_DURATION_IS_VALID (buf)) {
2410
if (GST_CLOCK_TIME_IS_VALID (parse->priv->last_pts)) {
2411
if (G_LIKELY (GST_BUFFER_DURATION (buf) <= parse->priv->last_pts))
2412
parse->priv->last_pts -= GST_BUFFER_DURATION (buf);
2414
parse->priv->last_pts = 0;
2415
GST_BUFFER_PTS (buf) = parse->priv->last_pts;
2416
GST_LOG_OBJECT (parse, "applied time %" GST_TIME_FORMAT,
2417
GST_TIME_ARGS (GST_BUFFER_PTS (buf)));
2419
if (GST_CLOCK_TIME_IS_VALID (parse->priv->last_dts)) {
2420
if (G_LIKELY (GST_BUFFER_DURATION (buf) <= parse->priv->last_dts))
2421
parse->priv->last_dts -= GST_BUFFER_DURATION (buf);
2423
parse->priv->last_dts = 0;
2424
GST_BUFFER_DTS (buf) = parse->priv->last_dts;
2425
GST_LOG_OBJECT (parse, "applied dts %" GST_TIME_FORMAT,
2426
GST_TIME_ARGS (GST_BUFFER_DTS (buf)));
2371
2429
/* no idea, very bad */
2372
2430
GST_WARNING_OBJECT (parse, "could not determine time for buffer");
2375
parse->priv->last_ts = GST_BUFFER_TIMESTAMP (buf);
2433
parse->priv->last_pts = GST_BUFFER_PTS (buf);
2434
parse->priv->last_dts = GST_BUFFER_DTS (buf);
2377
2436
/* reverse order for ascending sending */
2378
2437
/* send downstream at keyframe not preceded by a keyframe
2572
2631
/* move along with upstream timestamp (if any),
2573
2632
* but interpolate in between */
2574
timestamp = gst_adapter_prev_timestamp (parse->priv->adapter, NULL);
2575
if (GST_CLOCK_TIME_IS_VALID (timestamp) &&
2576
(parse->priv->prev_ts != timestamp)) {
2577
parse->priv->prev_ts = parse->priv->next_ts = timestamp;
2633
pts = gst_adapter_prev_pts (parse->priv->adapter, NULL);
2634
dts = gst_adapter_prev_dts (parse->priv->adapter, NULL);
2635
if (GST_CLOCK_TIME_IS_VALID (pts) && (parse->priv->prev_pts != pts)) {
2636
parse->priv->prev_pts = parse->priv->next_pts = pts;
2637
parse->priv->prev_dts = parse->priv->next_dts = dts;
2580
2640
/* always pass all available data */
2692
2752
GstFlowReturn ret;
2694
2754
GST_DEBUG_OBJECT (parse, "fragment ended; last_ts = %" GST_TIME_FORMAT
2695
", last_offset = %" G_GINT64_FORMAT, GST_TIME_ARGS (parse->priv->last_ts),
2696
parse->priv->last_offset);
2755
", last_offset = %" G_GINT64_FORMAT,
2756
GST_TIME_ARGS (parse->priv->last_pts), parse->priv->last_offset);
2698
if (!parse->priv->last_offset || parse->priv->last_ts <= parse->segment.start) {
2758
if (!parse->priv->last_offset
2759
|| parse->priv->last_pts <= parse->segment.start) {
2699
2760
GST_DEBUG_OBJECT (parse, "past start of segment %" GST_TIME_FORMAT,
2700
2761
GST_TIME_ARGS (parse->segment.start));
2701
2762
ret = GST_FLOW_EOS;
2705
2766
/* last fragment started at last_offset / last_ts;
2706
2767
* seek back 10s capped at 1MB */
2707
if (parse->priv->last_ts >= 10 * GST_SECOND)
2708
ts = parse->priv->last_ts - 10 * GST_SECOND;
2768
if (parse->priv->last_pts >= 10 * GST_SECOND)
2769
ts = parse->priv->last_pts - 10 * GST_SECOND;
2709
2770
/* if we are exact now, we will be more so going backwards */
2710
2771
if (parse->priv->exact_position) {
2711
2772
offset = gst_base_parse_find_offset (parse, ts, TRUE, NULL);
2948
3009
if (push_eos) {
2949
3010
/* Push pending events, including NEWSEGMENT events */
2950
3011
if (G_UNLIKELY (parse->priv->pending_events)) {
3012
GList *r = g_list_reverse (parse->priv->pending_events);
2953
for (l = parse->priv->pending_events; l != NULL; l = l->next) {
3015
parse->priv->pending_events = NULL;
3016
for (l = r; l != NULL; l = l->next) {
2954
3017
gst_pad_push_event (parse->srcpad, GST_EVENT (l->data));
2956
g_list_free (parse->priv->pending_events);
2957
parse->priv->pending_events = NULL;
2958
3020
parse->priv->pending_segment = FALSE;
2981
3044
goto baseparse_push;
2984
pull_mode = gst_query_has_scheduling_mode (query, GST_PAD_MODE_PULL);
3047
gst_query_parse_scheduling (query, &sched_flags, NULL, NULL, NULL);
3049
pull_mode = gst_query_has_scheduling_mode (query, GST_PAD_MODE_PULL)
3050
&& ((sched_flags & GST_SCHEDULING_FLAG_SEEKABLE) != 0);
2985
3052
gst_query_unref (query);
2987
3054
if (!pull_mode)
3045
3112
parse = GST_BASE_PARSE (parent);
3047
GST_DEBUG_OBJECT (parse, "sink activate mode %d, %d", mode, active);
3114
GST_DEBUG_OBJECT (parse, "sink %sactivate in %s mode",
3115
(active) ? "" : "de", gst_pad_mode_get_name (mode));
3049
3117
if (!gst_base_parse_activate (parse, active))
3050
3118
goto activate_failed;
3342
* gst_base_parse_set_pts_interpolation:
3343
* @parse: a #GstBaseParse
3344
* @passthrough: %TRUE if parser should interpolate PTS timestamps
3346
* By default, the base class will guess PTS timestamps using a simple
3347
* interpolation (previous timestamp + duration), which is incorrect for
3348
* data streams with reordering, where PTS can go backward. Sub-classes
3349
* implementing such formats should disable PTS interpolation.
3352
gst_base_parse_set_pts_interpolation (GstBaseParse * parse,
3353
gboolean pts_interpolate)
3355
parse->priv->pts_interpolate = pts_interpolate;
3356
GST_INFO_OBJECT (parse, "PTS interpolation: %s",
3357
(pts_interpolate) ? "yes" : "no");
3274
3361
* gst_base_parse_set_latency:
3275
3362
* @parse: a #GstBaseParse
3276
3363
* @min_latency: minimum parse latency
3582
3669
/* need initial positions; start and end */
3583
3670
lpos = parse->priv->first_frame_offset;
3584
ltime = parse->priv->first_frame_ts;
3671
ltime = parse->priv->first_frame_pts;
3585
3672
if (!gst_base_parse_get_duration (parse, GST_FORMAT_TIME, &htime)) {
3586
3673
GST_DEBUG_OBJECT (parse, "Unknown time duration, cannot bisect");
3587
3674
return GST_FLOW_ERROR;
3747
3834
GstSegment seeksegment = { 0, };
3748
3835
GstClockTime start_ts;
3837
/* try upstream first, unless we're driving the streaming thread ourselves */
3838
if (parse->priv->pad_mode != GST_PAD_MODE_PULL) {
3839
res = gst_pad_push_event (parse->sinkpad, gst_event_ref (event));
3750
3844
gst_event_parse_seek (event, &rate, &format, &flags,
3751
3845
&start_type, &start, &stop_type, &stop);
3755
3849
GST_TIME_FORMAT, gst_format_get_name (format), rate,
3756
3850
start_type, GST_TIME_ARGS (start), stop_type, GST_TIME_ARGS (stop));
3758
/* no negative rates in push mode */
3852
/* we can only handle TIME, so check if subclass can convert
3853
* to TIME format if it's some other format (such as DEFAULT) */
3854
if (format != GST_FORMAT_TIME) {
3855
if (!gst_base_parse_convert (parse, format, start, GST_FORMAT_TIME, &start)
3856
|| !gst_base_parse_convert (parse, format, stop, GST_FORMAT_TIME,
3858
goto no_convert_to_time;
3860
GST_INFO_OBJECT (parse, "converted %s format to start time "
3861
"%" GST_TIME_FORMAT " and stop time %" GST_TIME_FORMAT,
3862
gst_format_get_name (format), GST_TIME_ARGS (start),
3863
GST_TIME_ARGS (stop));
3865
format = GST_FORMAT_TIME;
3868
/* no negative rates in push mode (unless upstream takes care of that, but
3869
* we've already tried upstream and it didn't handle the seek request) */
3759
3870
if (rate < 0.0 && parse->priv->pad_mode == GST_PAD_MODE_PUSH)
3760
3871
goto negative_rate;
3762
/* For any format other than TIME, see if upstream handles
3763
* it directly or fail. For TIME, try upstream, but do it ourselves if
3764
* it fails upstream */
3765
res = gst_pad_push_event (parse->sinkpad, event);
3766
if (format != GST_FORMAT_TIME || res)
3873
if (rate < 0.0 && parse->priv->pad_mode == GST_PAD_MODE_PULL)
3874
goto negative_rate_pull_mode;
3769
3876
if (start_type != GST_SEEK_TYPE_SET ||
3770
3877
(stop_type != GST_SEEK_TYPE_SET && stop_type != GST_SEEK_TYPE_NONE))
3864
3971
/* This will be sent later in _loop() */
3865
3972
parse->priv->pending_segment = TRUE;
3866
3973
parse->priv->pending_events =
3867
g_list_append (parse->priv->pending_events,
3974
g_list_prepend (parse->priv->pending_events,
3868
3975
gst_event_new_segment (&parse->segment));
3870
3977
GST_DEBUG_OBJECT (parse, "Created newseg format %d, "
3900
4007
parse->priv->last_offset = seekpos;
3901
4008
parse->priv->seen_keyframe = FALSE;
3902
4009
parse->priv->discont = TRUE;
3903
parse->priv->next_ts = start_ts;
3904
parse->priv->last_ts = GST_CLOCK_TIME_NONE;
4010
parse->priv->next_pts = start_ts;
4011
parse->priv->next_dts = GST_CLOCK_TIME_NONE;
4012
parse->priv->last_dts = GST_CLOCK_TIME_NONE;
4013
parse->priv->last_pts = GST_CLOCK_TIME_NONE;
3905
4014
parse->priv->sync_offset = seekpos;
3906
4015
parse->priv->exact_position = accurate;