~ubuntu-branches/ubuntu/trusty/gstreamer1.0/trusty

« back to all changes in this revision

Viewing changes to libs/gst/base/gstbaseparse.c

  • Committer: Package Import Robot
  • Author(s): Sebastian Dröge
  • Date: 2012-09-14 09:04:41 UTC
  • mfrom: (1.1.4)
  • Revision ID: package-import@ubuntu.com-20120914090441-1ul912ezvm3xfael
Tags: 0.11.94-1
* New upstream release:
  + debian/libgstreamer.symbols:
    - Update symbols file.
  + debian/control.in:
    - Build-depend on gtk-doc >= 1.12.
  + debian/patches/0001-netclientclock-simplify-by-using-g_socket_condition_.patch:
    - Dropped, merged upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
246
246
 
247
247
  guint min_frame_size;
248
248
  gboolean passthrough;
 
249
  gboolean pts_interpolate;
249
250
  gboolean syncable;
250
251
  gboolean has_timing_info;
251
252
  guint fps_num, fps_den;
261
262
 
262
263
  gint64 offset;
263
264
  gint64 sync_offset;
264
 
  GstClockTime next_ts;
265
 
  GstClockTime prev_ts;
 
265
  GstClockTime next_pts;
 
266
  GstClockTime next_dts;
 
267
  GstClockTime prev_pts;
 
268
  GstClockTime prev_dts;
266
269
  GstClockTime frame_duration;
267
270
  gboolean seen_keyframe;
268
271
  gboolean is_video;
272
275
  guint64 bytecount;
273
276
  guint64 data_bytecount;
274
277
  guint64 acc_duration;
275
 
  GstClockTime first_frame_ts;
 
278
  GstClockTime first_frame_pts;
 
279
  GstClockTime first_frame_dts;
276
280
  gint64 first_frame_offset;
277
281
 
278
282
  gboolean post_min_bitrate;
315
319
  GSList *buffers_head;
316
320
  GSList *buffers_queued;
317
321
  GSList *buffers_send;
318
 
  GstClockTime last_ts;
 
322
  GstClockTime last_pts;
 
323
  GstClockTime last_dts;
319
324
  gint64 last_offset;
320
325
 
321
326
  /* Pending serialized events */
423
428
static GstFlowReturn gst_base_parse_parse_frame (GstBaseParse * parse,
424
429
    GstBaseParseFrame * frame);
425
430
 
426
 
static gboolean gst_base_parse_sink_eventfunc (GstBaseParse * parse,
 
431
static gboolean gst_base_parse_sink_default (GstBaseParse * parse,
427
432
    GstEvent * event);
428
433
 
429
 
static gboolean gst_base_parse_src_eventfunc (GstBaseParse * parse,
 
434
static gboolean gst_base_parse_src_default (GstBaseParse * parse,
430
435
    GstEvent * event);
431
436
 
432
437
static void gst_base_parse_drain (GstBaseParse * parse);
531
536
#endif
532
537
 
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;
537
542
 
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;
740
748
 
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;
743
752
 
744
753
  g_list_foreach (parse->priv->pending_events, (GFunc) gst_mini_object_unref,
779
788
{
780
789
  GstBuffer *buffer = frame->buffer;
781
790
 
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;
 
794
  }
 
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;
785
798
  }
786
799
  if (!GST_BUFFER_DURATION_IS_VALID (buffer) &&
787
800
      GST_CLOCK_TIME_IS_VALID (parse->priv->frame_duration)) {
855
868
static gboolean
856
869
gst_base_parse_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
857
870
{
858
 
  GstBaseParse *parse;
859
 
  GstBaseParseClass *bclass;
 
871
  GstBaseParse *parse = GST_BASE_PARSE (parent);
 
872
  GstBaseParseClass *bclass = GST_BASE_PARSE_GET_CLASS (parse);
860
873
  gboolean ret;
861
874
 
862
 
  parse = GST_BASE_PARSE (parent);
863
 
  bclass = GST_BASE_PARSE_GET_CLASS (parse);
864
 
 
865
 
  GST_DEBUG_OBJECT (parse, "handling event %d, %s", GST_EVENT_TYPE (event),
866
 
      GST_EVENT_TYPE_NAME (event));
867
 
 
868
 
  /* Cache all serialized events except EOS, SEGMENT and FLUSH_STOP if we have a
869
 
   * pending segment */
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) {
876
 
 
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);
880
 
 
881
 
    parse->priv->pending_events =
882
 
        g_list_append (parse->priv->pending_events, event);
883
 
    ret = TRUE;
884
 
  } else {
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);
889
 
 
890
 
    if (bclass->sink_event)
891
 
      ret = bclass->sink_event (parse, event);
892
 
    else {
893
 
      gst_event_unref (event);
894
 
      ret = FALSE;
895
 
    }
896
 
  }
897
 
 
898
 
  GST_DEBUG_OBJECT (parse, "event handled");
 
875
  ret = bclass->sink_event (parse, event);
899
876
 
900
877
  return ret;
901
878
}
902
879
 
903
880
 
904
 
/* gst_base_parse_sink_eventfunc:
 
881
/* gst_base_parse_sink_default:
905
882
 * @parse: #GstBaseParse.
906
883
 * @event: #GstEvent to be handled.
907
884
 *
913
890
 * Returns: %TRUE if the event was handled and not need forwarding.
914
891
 */
915
892
static gboolean
916
 
gst_base_parse_sink_eventfunc (GstBaseParse * parse, GstEvent * event)
 
893
gst_base_parse_sink_default (GstBaseParse * parse, GstEvent * event)
917
894
{
918
 
  gboolean ret;
 
895
  GstBaseParseClass *klass = GST_BASE_PARSE_GET_CLASS (parse);
 
896
  gboolean ret = FALSE;
 
897
  gboolean forward_immediate = FALSE;
 
898
 
 
899
  GST_DEBUG_OBJECT (parse, "handling event %d, %s", GST_EVENT_TYPE (event),
 
900
      GST_EVENT_TYPE_NAME (event));
919
901
 
920
902
  switch (GST_EVENT_TYPE (event)) {
921
903
    case GST_EVENT_CAPS:
922
904
    {
923
905
      GstCaps *caps;
924
 
      GstBaseParseClass *klass;
925
 
 
926
 
      klass = GST_BASE_PARSE_GET_CLASS (parse);
927
906
 
928
907
      gst_event_parse_caps (event, &caps);
929
908
      GST_DEBUG_OBJECT (parse, "caps: %" GST_PTR_FORMAT, caps);
935
914
 
936
915
      /* will send our own caps downstream */
937
916
      gst_event_unref (event);
 
917
      event = NULL;
938
918
      break;
939
919
    }
940
920
    case GST_EVENT_SEGMENT:
941
921
    {
942
922
      const GstSegment *in_segment;
943
923
      GstSegment out_segment;
944
 
      gint64 offset = 0, next_ts;
945
 
 
946
 
#if 0
947
 
      gdouble rate, applied_rate;
948
 
      GstFormat format;
949
 
      gint64 start, stop, pos, next_ts;
950
 
      gboolean update;
951
 
#endif
 
924
      gint64 offset = 0, next_pts;
952
925
 
953
926
      gst_event_parse_segment (event, &in_segment);
954
927
      gst_segment_init (&out_segment, GST_FORMAT_TIME);
984
957
          out_segment.stop = seek->segment.stop;
985
958
          out_segment.time = seek->segment.start;
986
959
 
987
 
          next_ts = seek->start_ts;
 
960
          next_pts = seek->start_ts;
988
961
          parse->priv->exact_position = seek->accurate;
989
962
          g_free (seek);
990
963
        } else {
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);
996
969
 
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;
1000
973
 
1001
974
          parse->priv->exact_position = (in_segment->start == 0);
1002
975
        }
1019
992
 
1020
993
        event = gst_event_new_segment (&out_segment);
1021
994
 
1022
 
        next_ts = 0;
 
995
        next_pts = 0;
1023
996
      } else {
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;
1028
1001
      }
1029
1002
 
1030
1003
      memcpy (&parse->segment, &out_segment, sizeof (GstSegment));
1037
1010
      /* save the segment for later, right before we push a new buffer so that
1038
1011
       * the caps are fixed and the next linked element can receive
1039
1012
       * the segment. */
1040
 
      parse->priv->pending_events =
1041
 
          g_list_append (parse->priv->pending_events, event);
1042
1013
      parse->priv->pending_segment = TRUE;
1043
1014
      ret = TRUE;
1044
1015
 
1052
1023
 
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;
1059
1031
      break;
1060
1032
    }
1061
1033
 
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);
1068
1038
      break;
1069
1039
 
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;
 
1048
 
 
1049
      forward_immediate = TRUE;
1078
1050
      break;
1079
1051
 
1080
1052
    case GST_EVENT_EOS:
1099
1071
        parse->priv->pending_events = NULL;
1100
1072
        parse->priv->pending_segment = FALSE;
1101
1073
      }
 
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);
 
1077
      }
 
1078
      forward_immediate = TRUE;
 
1079
      break;
 
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"
 
1084
#endif
 
1085
 
 
1086
      const GstStructure *s;
 
1087
      gboolean ev_still_state;
 
1088
 
 
1089
      s = gst_event_get_structure (event);
 
1090
      if (s != NULL &&
 
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);
 
1097
          else
 
1098
            gst_base_parse_finish_fragment (parse, TRUE);
 
1099
        }
 
1100
        forward_immediate = TRUE;
 
1101
      }
 
1102
      break;
 
1103
    }
 
1104
    case GST_EVENT_GAP:
 
1105
    {
 
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);
 
1109
      else
 
1110
        gst_base_parse_finish_fragment (parse, TRUE);
 
1111
      forward_immediate = TRUE;
 
1112
      break;
 
1113
    }
 
1114
    case GST_EVENT_TAG:
 
1115
      /* See if any bitrate tags were posted */
 
1116
      gst_base_parse_handle_tag (parse, event);
 
1117
      break;
 
1118
    default:
 
1119
      break;
 
1120
  }
 
1121
 
 
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
 
1129
   *
 
1130
   * For FLUSH_STOP this is required because it is expected
 
1131
   * to be forwarded immediately and no buffers are queued anyway.
 
1132
   */
 
1133
  if (event) {
 
1134
    if (!GST_EVENT_IS_SERIALIZED (event) || forward_immediate) {
1102
1135
      ret = gst_pad_push_event (parse->srcpad, event);
1103
 
      break;
1104
 
 
1105
 
    default:
1106
 
      ret =
1107
 
          gst_pad_event_default (parse->sinkpad, GST_OBJECT_CAST (parse),
1108
 
          event);
1109
 
      break;
 
1136
    } else {
 
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);
 
1141
      ret = TRUE;
 
1142
    }
1110
1143
  }
 
1144
 
 
1145
  GST_DEBUG_OBJECT (parse, "event handled");
 
1146
 
1111
1147
  return ret;
1112
1148
}
1113
1149
 
1203
1239
  return parse->priv->syncable;
1204
1240
}
1205
1241
 
1206
 
/* gst_base_parse_src_eventfunc:
 
1242
/* gst_base_parse_src_default:
1207
1243
 * @parse: #GstBaseParse.
1208
1244
 * @event: #GstEvent that was received.
1209
1245
 *
1212
1248
 * Returns: TRUE if the event was handled and can be dropped.
1213
1249
 */
1214
1250
static gboolean
1215
 
gst_base_parse_src_eventfunc (GstBaseParse * parse, GstEvent * event)
 
1251
gst_base_parse_src_default (GstBaseParse * parse, GstEvent * event)
1216
1252
{
1217
1253
  gboolean res = FALSE;
1218
1254
 
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;
1362
1397
        }
1363
1398
        parse->priv->estimated_duration = dest_value;
1778
1813
 
1779
1814
  /* track skipping */
1780
1815
  if (*skip > 0) {
1781
 
    GstClockTime timestamp;
 
1816
    GstClockTime pts, dts;
1782
1817
    GstBuffer *outbuf;
1783
1818
 
1784
1819
    GST_LOG_OBJECT (parse, "finding sync, skipping %d bytes", *skip);
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);
1795
1832
      outbuf = NULL;
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)) {
1855
1893
        gint64 off;
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);
 
1910
 
 
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;
 
1920
    }
1876
1921
  } else {
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;
1881
1926
  }
1882
1927
 
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);
1888
1933
 
1889
1934
  /* All OK, push queued frames if there are any */
1966
2011
 
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);
1969
2015
    GList *l;
1970
2016
 
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));
1973
2020
    }
1974
 
    g_list_free (parse->priv->pending_events);
1975
 
    parse->priv->pending_events = NULL;
 
2021
    g_list_free (r);
1976
2022
    parse->priv->pending_segment = FALSE;
1977
2023
  }
1978
2024
 
2290
2336
 
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 */
2350
2398
 
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);
2356
2404
 
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);
2365
 
      else
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);
 
2413
        else
 
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)));
 
2418
      }
 
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);
 
2422
        else
 
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)));
 
2427
      }
2370
2428
    } else {
2371
2429
      /* no idea, very bad */
2372
2430
      GST_WARNING_OBJECT (parse, "could not determine time for buffer");
2373
2431
    }
2374
2432
 
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);
2376
2435
 
2377
2436
    /* reverse order for ascending sending */
2378
2437
    /* send downstream at keyframe not preceded by a keyframe
2440
2499
  gint skip = -1;
2441
2500
  const guint8 *data;
2442
2501
  guint min_size, av;
2443
 
  GstClockTime timestamp;
 
2502
  GstClockTime pts, dts;
2444
2503
 
2445
2504
  parse = GST_BASE_PARSE (parent);
2446
2505
  bclass = GST_BASE_PARSE_GET_CLASS (parse);
2571
2630
 
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;
2578
2638
    }
2579
2639
 
2580
2640
    /* always pass all available data */
2692
2752
  GstFlowReturn ret;
2693
2753
 
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);
2697
2757
 
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;
2704
2765
 
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);
2951
3013
        GList *l;
2952
3014
 
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));
2955
3018
        }
2956
 
        g_list_free (parse->priv->pending_events);
2957
 
        parse->priv->pending_events = NULL;
 
3019
        g_list_free (r);
2958
3020
        parse->priv->pending_segment = FALSE;
2959
3021
      }
2960
3022
 
2967
3029
static gboolean
2968
3030
gst_base_parse_sink_activate (GstPad * sinkpad, GstObject * parent)
2969
3031
{
 
3032
  GstSchedulingFlags sched_flags;
2970
3033
  GstBaseParse *parse;
2971
3034
  GstQuery *query;
2972
3035
  gboolean pull_mode;
2981
3044
    goto baseparse_push;
2982
3045
  }
2983
3046
 
2984
 
  pull_mode = gst_query_has_scheduling_mode (query, GST_PAD_MODE_PULL);
 
3047
  gst_query_parse_scheduling (query, &sched_flags, NULL, NULL, NULL);
 
3048
 
 
3049
  pull_mode = gst_query_has_scheduling_mode (query, GST_PAD_MODE_PULL)
 
3050
      && ((sched_flags & GST_SCHEDULING_FLAG_SEEKABLE) != 0);
 
3051
 
2985
3052
  gst_query_unref (query);
2986
3053
 
2987
3054
  if (!pull_mode)
3044
3111
 
3045
3112
  parse = GST_BASE_PARSE (parent);
3046
3113
 
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));
3048
3116
 
3049
3117
  if (!gst_base_parse_activate (parse, active))
3050
3118
    goto activate_failed;
3053
3121
    case GST_PAD_MODE_PULL:
3054
3122
      if (active) {
3055
3123
        parse->priv->pending_events =
3056
 
            g_list_append (parse->priv->pending_events,
 
3124
            g_list_prepend (parse->priv->pending_events,
3057
3125
            gst_event_new_segment (&parse->segment));
3058
3126
        parse->priv->pending_segment = TRUE;
3059
3127
        result = TRUE;
3107
3175
  if (duration != parse->priv->duration) {
3108
3176
    GstMessage *m;
3109
3177
 
3110
 
    m = gst_message_new_duration (GST_OBJECT (parse), fmt, duration);
 
3178
    m = gst_message_new_duration_changed (GST_OBJECT (parse));
3111
3179
    gst_element_post_message (GST_ELEMENT (parse), m);
3112
3180
 
3113
3181
    /* TODO: what about duration tag? */
3271
3339
}
3272
3340
 
3273
3341
/**
 
3342
 * gst_base_parse_set_pts_interpolation:
 
3343
 * @parse: a #GstBaseParse
 
3344
 * @passthrough: %TRUE if parser should interpolate PTS timestamps
 
3345
 *
 
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.
 
3350
 */
 
3351
void
 
3352
gst_base_parse_set_pts_interpolation (GstBaseParse * parse,
 
3353
    gboolean pts_interpolate)
 
3354
{
 
3355
  parse->priv->pts_interpolate = pts_interpolate;
 
3356
  GST_INFO_OBJECT (parse, "PTS interpolation: %s",
 
3357
      (pts_interpolate) ? "yes" : "no");
 
3358
}
 
3359
 
 
3360
/**
3274
3361
 * gst_base_parse_set_latency:
3275
3362
 * @parse: a #GstBaseParse
3276
3363
 * @min_latency: minimum parse latency
3581
3668
 
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;
3749
3836
 
 
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));
 
3840
    if (res)
 
3841
      goto done;
 
3842
  }
 
3843
 
3750
3844
  gst_event_parse_seek (event, &rate, &format, &flags,
3751
3845
      &start_type, &start, &stop_type, &stop);
3752
3846
 
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));
3757
3851
 
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,
 
3857
            &stop))
 
3858
      goto no_convert_to_time;
 
3859
 
 
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));
 
3864
 
 
3865
    format = GST_FORMAT_TIME;
 
3866
  }
 
3867
 
 
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;
3761
3872
 
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)
3767
 
    goto done;
 
3873
  if (rate < 0.0 && parse->priv->pad_mode == GST_PAD_MODE_PULL)
 
3874
    goto negative_rate_pull_mode;
3768
3875
 
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));
3869
3976
 
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;
3907
4016
    }
3955
4064
  }
3956
4065
 
3957
4066
done:
 
4067
  gst_event_unref (event);
3958
4068
  return res;
3959
4069
 
3960
4070
  /* ERRORS */
 
4071
negative_rate_pull_mode:
 
4072
  {
 
4073
    GST_FIXME_OBJECT (parse, "negative playback in pull mode needs fixing");
 
4074
    res = FALSE;
 
4075
    goto done;
 
4076
  }
3961
4077
negative_rate:
3962
4078
  {
3963
4079
    GST_DEBUG_OBJECT (parse, "negative playback rates delegated upstream.");
3970
4086
    res = FALSE;
3971
4087
    goto done;
3972
4088
  }
 
4089
no_convert_to_time:
 
4090
  {
 
4091
    GST_DEBUG_OBJECT (parse, "seek in %s format was requested, but subclass "
 
4092
        "couldn't convert that into TIME format", gst_format_get_name (format));
 
4093
    res = FALSE;
 
4094
    goto done;
 
4095
  }
3973
4096
convert_failed:
3974
4097
  {
3975
4098
    GST_DEBUG_OBJECT (parse, "conversion TIME to BYTES failed.");