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

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Sebastian Dröge
  • Date: 2012-05-21 11:14:06 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120521111406-1wfas0o9fdaxjyo8
Tags: 0.11.91-1
* New upstream release, "I will give you five magic beans!":
  + debian/libgstreamer.symbols:
    - Update symbols file.
* debian/libgstreamer-dev.install:
  + Don't ship useless .la file for the core plugins.
  + Don't ship .a and .la files for the library.
* debian/control.in:
  + Update debhelper dependency version and Standards-Version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
124
124
GST_DEBUG_CATEGORY_STATIC (gst_adapter_debug);
125
125
#define GST_CAT_DEFAULT gst_adapter_debug
126
126
 
127
 
#define GST_ADAPTER_GET_PRIVATE(obj)  \
128
 
   (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_ADAPTER, GstAdapterPrivate))
129
 
 
130
 
struct _GstAdapterPrivate
 
127
struct _GstAdapter
131
128
{
 
129
  GObject object;
 
130
 
 
131
  /*< private > */
 
132
  GSList *buflist;
 
133
  GSList *buflist_end;
 
134
  gsize size;
 
135
  gsize skip;
 
136
 
 
137
  /* we keep state of assembled pieces */
 
138
  gpointer assembled_data;
 
139
  gsize assembled_size;
 
140
  gsize assembled_len;
 
141
 
132
142
  GstClockTime pts;
133
143
  guint64 pts_distance;
134
144
  GstClockTime dts;
140
150
  GstMapInfo info;
141
151
};
142
152
 
 
153
struct _GstAdapterClass
 
154
{
 
155
  GObjectClass parent_class;
 
156
};
 
157
 
143
158
#define _do_init \
144
159
  GST_DEBUG_CATEGORY_INIT (gst_adapter_debug, "adapter", 0, "object to splice and merge buffers to desired size")
145
160
#define gst_adapter_parent_class parent_class
153
168
{
154
169
  GObjectClass *object = G_OBJECT_CLASS (klass);
155
170
 
156
 
  g_type_class_add_private (klass, sizeof (GstAdapterPrivate));
157
 
 
158
171
  object->dispose = gst_adapter_dispose;
159
172
  object->finalize = gst_adapter_finalize;
160
173
}
162
175
static void
163
176
gst_adapter_init (GstAdapter * adapter)
164
177
{
165
 
  adapter->priv = GST_ADAPTER_GET_PRIVATE (adapter);
166
178
  adapter->assembled_data = g_malloc (DEFAULT_SIZE);
167
179
  adapter->assembled_size = DEFAULT_SIZE;
168
 
  adapter->priv->pts = GST_CLOCK_TIME_NONE;
169
 
  adapter->priv->pts_distance = 0;
170
 
  adapter->priv->dts = GST_CLOCK_TIME_NONE;
171
 
  adapter->priv->dts_distance = 0;
 
180
  adapter->pts = GST_CLOCK_TIME_NONE;
 
181
  adapter->pts_distance = 0;
 
182
  adapter->dts = GST_CLOCK_TIME_NONE;
 
183
  adapter->dts_distance = 0;
172
184
}
173
185
 
174
186
static void
213
225
void
214
226
gst_adapter_clear (GstAdapter * adapter)
215
227
{
216
 
  GstAdapterPrivate *priv;
217
 
 
218
228
  g_return_if_fail (GST_IS_ADAPTER (adapter));
219
229
 
220
 
  priv = adapter->priv;
221
 
 
222
 
  if (priv->info.memory)
 
230
  if (adapter->info.memory)
223
231
    gst_adapter_unmap (adapter);
224
232
 
225
233
  g_slist_foreach (adapter->buflist, (GFunc) gst_mini_object_unref, NULL);
229
237
  adapter->size = 0;
230
238
  adapter->skip = 0;
231
239
  adapter->assembled_len = 0;
232
 
  priv->pts = GST_CLOCK_TIME_NONE;
233
 
  priv->pts_distance = 0;
234
 
  priv->dts = GST_CLOCK_TIME_NONE;
235
 
  priv->dts_distance = 0;
236
 
  priv->scan_offset = 0;
237
 
  priv->scan_entry = NULL;
 
240
  adapter->pts = GST_CLOCK_TIME_NONE;
 
241
  adapter->pts_distance = 0;
 
242
  adapter->dts = GST_CLOCK_TIME_NONE;
 
243
  adapter->dts_distance = 0;
 
244
  adapter->scan_offset = 0;
 
245
  adapter->scan_entry = NULL;
238
246
}
239
247
 
240
248
static inline void
245
253
  pts = GST_BUFFER_PTS (buf);
246
254
  if (GST_CLOCK_TIME_IS_VALID (pts)) {
247
255
    GST_LOG_OBJECT (adapter, "new pts %" GST_TIME_FORMAT, GST_TIME_ARGS (pts));
248
 
    adapter->priv->pts = pts;
249
 
    adapter->priv->pts_distance = 0;
 
256
    adapter->pts = pts;
 
257
    adapter->pts_distance = 0;
250
258
  }
251
259
  dts = GST_BUFFER_DTS (buf);
252
260
  if (GST_CLOCK_TIME_IS_VALID (dts)) {
253
261
    GST_LOG_OBJECT (adapter, "new dts %" GST_TIME_FORMAT, GST_TIME_ARGS (dts));
254
 
    adapter->priv->dts = dts;
255
 
    adapter->priv->dts_distance = 0;
 
262
    adapter->dts = dts;
 
263
    adapter->dts_distance = 0;
256
264
  }
257
265
}
258
266
 
267
275
 
268
276
  /* first step, do skipping */
269
277
  /* we might well be copying where we were scanning */
270
 
  if (adapter->priv->scan_entry && (adapter->priv->scan_offset <= skip)) {
271
 
    g = adapter->priv->scan_entry;
272
 
    skip -= adapter->priv->scan_offset;
 
278
  if (adapter->scan_entry && (adapter->scan_offset <= skip)) {
 
279
    g = adapter->scan_entry;
 
280
    skip -= adapter->scan_offset;
273
281
  } else {
274
282
    g = adapter->buflist;
275
283
  }
341
349
  }
342
350
}
343
351
 
 
352
#if 0
344
353
/* Internal method only. Tries to merge buffers at the head of the queue
345
354
 * to form a single larger buffer of size 'size'.
346
355
 *
359
368
    return FALSE;
360
369
 
361
370
  head = g->data;
 
371
 
 
372
  hsize = gst_buffer_get_size (head);
 
373
 
 
374
  /* Remove skipped part from the buffer (otherwise the buffer might grow indefinitely) */
 
375
  head = gst_buffer_make_writable (head);
 
376
  gst_buffer_resize (head, adapter->skip, hsize - adapter->skip);
 
377
  hsize -= adapter->skip;
 
378
  adapter->skip = 0;
 
379
  g->data = head;
 
380
 
362
381
  g = g_slist_next (g);
363
382
 
364
 
  /* How large do we want our head buffer? The requested size, plus whatever's
365
 
   * been skipped already */
366
 
  size += adapter->skip;
367
 
  hsize = gst_buffer_get_size (head);
368
 
 
369
383
  while (g != NULL && hsize < size) {
370
384
    cur = g->data;
371
385
    /* Merge the head buffer and the next in line */
383
397
    g->data = head;
384
398
 
385
399
    /* invalidate scan position */
386
 
    adapter->priv->scan_offset = 0;
387
 
    adapter->priv->scan_entry = NULL;
 
400
    adapter->scan_offset = 0;
 
401
    adapter->scan_entry = NULL;
388
402
 
389
403
    g = g_slist_next (g);
390
404
  }
391
405
 
392
406
  return ret;
393
407
}
 
408
#endif
394
409
 
395
410
/**
396
411
 * gst_adapter_map:
417
432
gconstpointer
418
433
gst_adapter_map (GstAdapter * adapter, gsize size)
419
434
{
420
 
  GstAdapterPrivate *priv;
421
435
  GstBuffer *cur;
422
436
  gsize skip, csize;
423
437
  gsize toreuse, tocopy;
426
440
  g_return_val_if_fail (GST_IS_ADAPTER (adapter), NULL);
427
441
  g_return_val_if_fail (size > 0, NULL);
428
442
 
429
 
  priv = adapter->priv;
430
 
 
431
 
  if (priv->info.memory)
 
443
  if (adapter->info.memory)
432
444
    gst_adapter_unmap (adapter);
433
445
 
434
446
  /* we don't have enough data, return NULL. This is unlikely
441
453
  if (adapter->assembled_len >= size)
442
454
    return adapter->assembled_data;
443
455
 
 
456
#if 0
444
457
  do {
 
458
#endif
445
459
    cur = adapter->buflist->data;
446
460
    skip = adapter->skip;
447
461
 
448
462
    csize = gst_buffer_get_size (cur);
449
463
    if (csize >= size + skip) {
450
 
      if (!gst_buffer_map (cur, &priv->info, GST_MAP_READ))
 
464
      if (!gst_buffer_map (cur, &adapter->info, GST_MAP_READ))
451
465
        return FALSE;
452
466
 
453
 
      return (guint8 *) priv->info.data + skip;
 
467
      return (guint8 *) adapter->info.data + skip;
454
468
    }
455
469
    /* We may be able to efficiently merge buffers in our pool to
456
470
     * gather a big enough chunk to return it from the head buffer directly */
 
471
#if 0
457
472
  } while (gst_adapter_try_to_merge_up (adapter, size));
 
473
#endif
458
474
 
459
475
  /* see how much data we can reuse from the assembled memory and how much
460
476
   * we need to copy */
498
514
void
499
515
gst_adapter_unmap (GstAdapter * adapter)
500
516
{
501
 
  GstAdapterPrivate *priv;
502
 
 
503
517
  g_return_if_fail (GST_IS_ADAPTER (adapter));
504
518
 
505
 
  priv = adapter->priv;
506
 
 
507
 
  if (priv->info.memory) {
 
519
  if (adapter->info.memory) {
508
520
    GstBuffer *cur = adapter->buflist->data;
509
521
    GST_LOG_OBJECT (adapter, "unmap memory buffer %p", cur);
510
 
    gst_buffer_unmap (cur, &priv->info);
511
 
    priv->info.memory = NULL;
 
522
    gst_buffer_unmap (cur, &adapter->info);
 
523
    adapter->info.memory = NULL;
512
524
  }
513
525
}
514
526
 
553
565
{
554
566
  GstBuffer *cur;
555
567
  gsize size;
556
 
  GstAdapterPrivate *priv;
557
568
  GSList *g;
558
569
 
559
570
  GST_LOG_OBJECT (adapter, "flushing %" G_GSIZE_FORMAT " bytes", flush);
560
571
 
561
 
  priv = adapter->priv;
562
 
 
563
 
  if (priv->info.memory)
 
572
  if (adapter->info.memory)
564
573
    gst_adapter_unmap (adapter);
565
574
 
566
575
  /* clear state */
570
579
  /* take skip into account */
571
580
  flush += adapter->skip;
572
581
  /* distance is always at least the amount of skipped bytes */
573
 
  priv->pts_distance -= adapter->skip;
574
 
  priv->dts_distance -= adapter->skip;
 
582
  adapter->pts_distance -= adapter->skip;
 
583
  adapter->dts_distance -= adapter->skip;
575
584
 
576
585
  g = adapter->buflist;
577
586
  cur = g->data;
579
588
  while (flush >= size) {
580
589
    /* can skip whole buffer */
581
590
    GST_LOG_OBJECT (adapter, "flushing out head buffer");
582
 
    priv->pts_distance += size;
583
 
    priv->dts_distance += size;
 
591
    adapter->pts_distance += size;
 
592
    adapter->dts_distance += size;
584
593
    flush -= size;
585
594
 
586
595
    gst_buffer_unref (cur);
599
608
  adapter->buflist = g;
600
609
  /* account for the remaining bytes */
601
610
  adapter->skip = flush;
602
 
  adapter->priv->pts_distance += flush;
603
 
  adapter->priv->dts_distance += flush;
 
611
  adapter->pts_distance += flush;
 
612
  adapter->dts_distance += flush;
604
613
  /* invalidate scan position */
605
 
  priv->scan_offset = 0;
606
 
  priv->scan_entry = NULL;
 
614
  adapter->scan_offset = 0;
 
615
  adapter->scan_entry = NULL;
607
616
}
608
617
 
609
618
void
754
763
    buffer = gst_buffer_copy_region (cur, GST_BUFFER_COPY_ALL, skip, nbytes);
755
764
    goto done;
756
765
  }
757
 
 
 
766
#if 0
758
767
  if (gst_adapter_try_to_merge_up (adapter, nbytes)) {
759
768
    /* Merged something, let's try again for sub-buffering */
760
769
    cur = adapter->buflist->data;
 
770
    skip = adapter->skip;
761
771
    if (gst_buffer_get_size (cur) >= nbytes + skip) {
762
772
      GST_LOG_OBJECT (adapter, "providing buffer of %" G_GSIZE_FORMAT " bytes"
763
773
          " via sub-buffer", nbytes);
765
775
      goto done;
766
776
    }
767
777
  }
 
778
#endif
768
779
 
769
780
  data = gst_adapter_take_internal (adapter, nbytes);
770
781
 
903
914
  g_return_val_if_fail (GST_IS_ADAPTER (adapter), GST_CLOCK_TIME_NONE);
904
915
 
905
916
  if (distance)
906
 
    *distance = adapter->priv->pts_distance;
 
917
    *distance = adapter->pts_distance;
907
918
 
908
 
  return adapter->priv->pts;
 
919
  return adapter->pts;
909
920
}
910
921
 
911
922
/**
930
941
  g_return_val_if_fail (GST_IS_ADAPTER (adapter), GST_CLOCK_TIME_NONE);
931
942
 
932
943
  if (distance)
933
 
    *distance = adapter->priv->dts_distance;
 
944
    *distance = adapter->dts_distance;
934
945
 
935
 
  return adapter->priv->dts;
 
946
  return adapter->dts;
936
947
}
937
948
 
938
949
/**
983
994
 
984
995
  /* first step, do skipping and position on the first buffer */
985
996
  /* optimistically assume scanning continues sequentially */
986
 
  if (adapter->priv->scan_entry && (adapter->priv->scan_offset <= skip)) {
987
 
    g = adapter->priv->scan_entry;
988
 
    skip -= adapter->priv->scan_offset;
 
997
  if (adapter->scan_entry && (adapter->scan_offset <= skip)) {
 
998
    g = adapter->scan_entry;
 
999
    skip -= adapter->scan_offset;
989
1000
  } else {
990
1001
    g = adapter->buflist;
991
 
    adapter->priv->scan_offset = 0;
992
 
    adapter->priv->scan_entry = NULL;
 
1002
    adapter->scan_offset = 0;
 
1003
    adapter->scan_entry = NULL;
993
1004
  }
994
1005
  buf = g->data;
995
1006
  bsize = gst_buffer_get_size (buf);
996
1007
  while (G_UNLIKELY (skip >= bsize)) {
997
1008
    skip -= bsize;
998
1009
    g = g_slist_next (g);
999
 
    adapter->priv->scan_offset += bsize;
1000
 
    adapter->priv->scan_entry = g;
 
1010
    adapter->scan_offset += bsize;
 
1011
    adapter->scan_entry = g;
1001
1012
    buf = g->data;
1002
1013
    bsize = gst_buffer_get_size (buf);
1003
1014
  }
1035
1046
    /* nothing found yet, go to next buffer */
1036
1047
    skip += bsize;
1037
1048
    g = g_slist_next (g);
1038
 
    adapter->priv->scan_offset += info.size;
1039
 
    adapter->priv->scan_entry = g;
 
1049
    adapter->scan_offset += info.size;
 
1050
    adapter->scan_entry = g;
1040
1051
    gst_buffer_unmap (buf, &info);
1041
1052
    buf = g->data;
1042
1053