~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-08-08 18:12:33 UTC
  • mfrom: (1.1.3)
  • Revision ID: package-import@ubuntu.com-20120808181233-riejwxprfsxh1njl
Tags: 0.11.93-1
* New upstream release:
  + debian/libgstreamer.symbols:
    - Update symbols file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
337
337
  gboolean detecting;
338
338
  GList *detect_buffers;
339
339
  guint detect_buffers_size;
 
340
 
 
341
  /* if TRUE, a STREAM_START event needs to be pushed */
 
342
  gboolean push_stream_start;
340
343
};
341
344
 
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.
638
 
 *
639
 
 * Since: 0.10.33
640
641
 */
641
642
void
642
643
gst_base_parse_frame_init (GstBaseParseFrame * frame)
660
661
 *
661
662
 * Returns: a newly-allocated #GstBaseParseFrame. Free with
662
663
 *     gst_base_parse_frame_free() when no longer needed.
663
 
 *
664
 
 * Since: 0.10.33
665
664
 */
666
665
GstBaseParseFrame *
667
666
gst_base_parse_frame_new (GstBuffer * buffer, GstBaseParseFrameFlags flags,
1242
1241
 * Default implementation of "convert" vmethod in #GstBaseParse class.
1243
1242
 *
1244
1243
 * Returns: TRUE if conversion was successful.
1245
 
 *
1246
 
 * Since: 0.10.33
1247
1244
 */
1248
1245
gboolean
1249
1246
gst_base_parse_convert_default (GstBaseParse * parse,
1407
1404
      parse->priv->max_bitrate);
1408
1405
 
1409
1406
  if (taglist != NULL) {
1410
 
    gst_pad_push_event (parse->srcpad, gst_event_new_tag ("GstParser",
1411
 
            taglist));
 
1407
    gst_pad_push_event (parse->srcpad, gst_event_new_tag (taglist));
1412
1408
  }
1413
1409
}
1414
1410
 
1512
1508
 * to the new entry, etc.
1513
1509
 *
1514
1510
 * Returns: #gboolean indicating whether entry was added
1515
 
 *
1516
 
 * Since: 0.10.33
1517
1511
 */
1518
1512
gboolean
1519
1513
gst_base_parse_add_index_entry (GstBaseParse * parse, guint64 offset,
1843
1837
 
1844
1838
  g_return_val_if_fail (frame != NULL, GST_FLOW_ERROR);
1845
1839
 
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);
1850
 
  }
1851
 
 
1852
1840
  buffer = frame->buffer;
1853
1841
  offset = frame->offset;
1854
1842
 
1922
1910
 * This must be called with sinkpad STREAM_LOCK held.
1923
1911
 *
1924
1912
 * Returns: #GstFlowReturn
1925
 
 *
1926
 
 * Since: 0.10.33
1927
1913
 */
1928
1914
GstFlowReturn
1929
1915
gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
2139
2125
 * caller retains ownership of @frame.
2140
2126
 *
2141
2127
 * Returns: a #GstFlowReturn that should be escalated to caller (of caller)
2142
 
 *
2143
 
 * Since: 0.11.1
2144
2128
 */
2145
2129
GstFlowReturn
2146
2130
gst_base_parse_finish_frame (GstBaseParse * parse, GstBaseParseFrame * frame,
2157
2141
  GST_LOG_OBJECT (parse, "finished frame at offset %" G_GUINT64_FORMAT ", "
2158
2142
      "flushing size %d", frame->offset, size);
2159
2143
 
 
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);
 
2148
  }
 
2149
 
 
2150
  parse->priv->flushed += size;
 
2151
 
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);
2164
2156
    goto exit;
2165
2157
  }
2166
2158
 
2167
 
  parse->priv->flushed += size;
2168
 
 
2169
2159
  /* either PUSH or PULL mode arranges for adapter data */
2170
2160
  /* ensure output buffer */
2171
2161
  if (!frame->out_buffer) {
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,
2762
 
    gboolean full)
 
2751
gst_base_parse_scan_frame (GstBaseParse * parse, GstBaseParseClass * klass)
2763
2752
{
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);
2860
2849
 
 
2850
  GST_DEBUG_OBJECT (parse, "hello");
 
2851
 
 
2852
  if (G_UNLIKELY (parse->priv->push_stream_start)) {
 
2853
    gchar *stream_id;
 
2854
 
 
2855
    stream_id =
 
2856
        gst_pad_create_stream_id (parse->srcpad, GST_ELEMENT_CAST (parse),
 
2857
        NULL);
 
2858
 
 
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;
 
2862
    g_free (stream_id);
 
2863
  }
 
2864
 
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 */
2870
2874
    }
2871
2875
  }
2872
2876
 
2873
 
  ret = gst_base_parse_scan_frame (parse, klass, TRUE);
 
2877
  ret = gst_base_parse_scan_frame (parse, klass);
2874
2878
  if (ret != GST_FLOW_OK)
2875
2879
    goto done;
2876
2880
 
2911
2915
 
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) {
2915
2919
        gint64 stop;
2916
2920
 
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));
2926
2932
      } else {
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;
2987
2993
 
 
2994
  parse->priv->push_stream_start = TRUE;
 
2995
 
2988
2996
  return gst_pad_start_task (sinkpad, (GstTaskFunction) gst_base_parse_loop,
2989
 
      sinkpad);
 
2997
      sinkpad, NULL);
2990
2998
  /* fallback */
2991
2999
baseparse_push:
2992
3000
  {
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
3086
3094
 * frames.
3087
 
 *
3088
 
 * Since: 0.10.33
3089
3095
 */
3090
3096
void
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()).
3136
 
 *
3137
 
 * Since: 0.10.33
3138
3142
 */
3139
3143
void
3140
3144
gst_base_parse_set_average_bitrate (GstBaseParse * parse, guint bitrate)
3151
3155
 *
3152
3156
 * Subclass can use this function to tell the base class that it needs to
3153
3157
 * give at least #min_size buffers.
3154
 
 *
3155
 
 * Since: 0.10.33
3156
3158
 */
3157
3159
void
3158
3160
gst_base_parse_set_min_frame_size (GstBaseParse * parse, guint min_size)
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.
3179
 
 *
3180
 
 * Since: 0.10.33
3181
3181
 */
3182
3182
void
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.
3229
 
 *
3230
 
 * Since: 0.10.33
3231
3229
 */
3232
3230
void
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.
3247
 
 *
3248
 
 * Since: 0.10.33
3249
3245
 */
3250
3246
void
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.
3269
 
 *
3270
 
 * Since: 0.10.33
3271
3265
 */
3272
3266
void
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.
3288
 
 *
3289
 
 * Since: 0.10.36
3290
3282
 */
3291
3283
void
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;
3749
3741
  gdouble rate;
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;
3757
3749
 
3758
3750
  gst_event_parse_seek (event, &rate, &format, &flags,
3759
 
      &cur_type, &cur, &stop_type, &stop);
 
3751
      &start_type, &start, &stop_type, &stop);
3760
3752
 
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));
3765
3757
 
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;
3769
3761
 
3770
 
  if (cur_type != GST_SEEK_TYPE_SET ||
3771
 
      (stop_type != GST_SEEK_TYPE_SET && stop_type != GST_SEEK_TYPE_NONE))
3772
 
    goto wrong_type;
3773
 
 
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 */
3778
3766
  if (format != GST_FORMAT_TIME || res)
3779
3767
    goto done;
3780
3768
 
 
3769
  if (start_type != GST_SEEK_TYPE_SET ||
 
3770
      (stop_type != GST_SEEK_TYPE_SET && stop_type != GST_SEEK_TYPE_NONE))
 
3771
    goto wrong_type;
 
3772
 
3781
3773
  /* get flush flag */
3782
3774
  flush = flags & GST_SEEK_FLAG_FLUSH;
3783
3775
 
3787
3779
 
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);
3791
3783
 
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 */
3916
3908
 
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);
3920
3912
 
3921
3913
    GST_PAD_STREAM_UNLOCK (parse->sinkpad);
3922
3914
 
3997
3989
 
3998
3990
  gst_event_parse_tag (event, &taglist);
3999
3991
 
 
3992
  /* We only care about stream tags here */
 
3993
  if (gst_tag_list_get_scope (taglist) != GST_TAG_SCOPE_STREAM)
 
3994
    return;
 
3995
 
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;