~ubuntu-branches/ubuntu/trusty/vdr-plugin-xineliboutput/trusty-proposed

« back to all changes in this revision

Viewing changes to tools/ts.c

  • Committer: Bazaar Package Importer
  • Author(s): Tobias Grimm
  • Date: 2010-05-02 15:19:11 UTC
  • mfrom: (1.2.1 upstream) (3.1.6 sid)
  • Revision ID: james.westby@ubuntu.com-20100502151911-76o36blrqp5jjsgb
Tags: 1.0.6~cvs20100502.0851-1
* New Upstream Snapshot
* source/format 1.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
 * See the main source file 'xineliboutput.c' for copyright information and
5
5
 * how to reach the author.
6
6
 *
7
 
 * $Id: ts.c,v 1.14 2009/09/09 11:58:40 phintuka Exp $
 
7
 * $Id: ts.c,v 1.20 2010/02/03 10:09:35 phintuka Exp $
8
8
 *
9
9
 */
10
10
 
529
529
 
530
530
  uint8_t  inside_pes; /* Scanning ES (PES start code seen and skipped) */
531
531
 
532
 
  uint32_t buf_len;    /* bytes queued */
533
 
  uint32_t buf_size;   /* buffer size */
 
532
  size_t   buf_len;    /* bytes queued */
 
533
  size_t   buf_size;   /* buffer size */
534
534
  uint8_t  buf[0];     /* payload: partial PES / video stream header etc. */
535
535
};
536
536
 
537
 
ts_state_t *ts_state_init(int buffer_size)
 
537
ts_state_t *ts_state_init(size_t buffer_size)
538
538
{
539
539
  if (buffer_size < 8 * TS_SIZE)
540
540
    buffer_size = 8 * TS_SIZE;
 
541
  if (buffer_size > 4*1024*1024) {
 
542
    LOGMSG("ERROR: ts_state_init(%zd)", buffer_size);
 
543
    buffer_size = 4*1024*1024;
 
544
  }
541
545
 
542
546
  ts_state_t *ts = (ts_state_t*)calloc(1, sizeof(ts_state_t) + buffer_size);
543
 
  ts->buf_size = buffer_size;
 
547
  if (ts) {
 
548
    ts->buf_size = buffer_size;
 
549
  }
 
550
 
544
551
  return ts;
545
552
}
546
553
 
547
554
void ts_state_reset(ts_state_t *ts)
548
555
{
549
 
  int buf_size = ts->buf_size;
550
 
  memset(ts, 0, sizeof(ts_state_t));
551
 
  ts->buf_size = buf_size;
 
556
  if (ts) {
 
557
    size_t buf_size = ts->buf_size;
 
558
    memset(ts, 0, sizeof(ts_state_t));
 
559
    ts->buf_size = buf_size;
 
560
  }
552
561
}
553
562
 
554
563
void ts_state_dispose(ts_state_t *ts)
563
572
 *  - PUSI resets the buffer
564
573
 *  - all data before first PUSI is discarded
565
574
 */
566
 
static int ts_add_payload(ts_state_t *ts, const uint8_t *data)
 
575
static size_t ts_add_payload(ts_state_t *ts, const uint8_t *data)
567
576
{
568
577
  /* start from PUSI */
569
578
  if (!ts->pusi_seen) {
574
583
  }
575
584
 
576
585
  if (ts->buf_len >= ts->buf_size - TS_SIZE) {
577
 
    LOGMSG("ts_add_payload: buffer full");
 
586
    LOGDBG("ts_add_payload: buffer full");
578
587
    ts->buf_len -= TS_SIZE;
579
 
    memcpy(ts->buf, ts->buf+TS_SIZE, ts->buf_len);
 
588
    memmove(ts->buf, ts->buf+TS_SIZE, ts->buf_len);
580
589
  }
581
590
 
582
 
  int len = ts_PAYLOAD_SIZE(data);
 
591
  size_t len = ts_PAYLOAD_SIZE(data);
583
592
  if (len > 0) {
584
593
    memcpy(ts->buf + ts->buf_len, ts_GET_PAYLOAD(data), len);
585
594
    ts->buf_len += len;
591
600
/*
592
601
 * ts_skip_payload()
593
602
 */
594
 
static void ts_skip_payload(ts_state_t *ts, unsigned int n)
 
603
static void ts_skip_payload(ts_state_t *ts, size_t n)
595
604
{
596
605
  if (n < ts->buf_len) {
597
606
    ts->buf_len -= n;
598
 
    memcpy(ts->buf, ts->buf + n, ts->buf_len);
 
607
    memmove(ts->buf, ts->buf + n, ts->buf_len);
599
608
  } else {
600
609
    ts->buf_len = 0;
601
610
  }
607
616
 * - discard all data until startcode (00 00 01) is found
608
617
 * - returns number of bytes left
609
618
 */
610
 
static int ts_scan_startcode(ts_state_t *ts)
 
619
static size_t ts_scan_startcode(ts_state_t *ts)
611
620
{
612
621
  if (ts->buf_len > 2) {
613
622
    /* scan for PES or MPEG 00 00 01 */
614
 
    unsigned int i = 0, n = ts->buf_len - 2;
 
623
    size_t i = 0, n = ts->buf_len - 2;
615
624
    while (i < n) {
616
 
      if (ts->buf[i+2] != 1)
617
 
        i += 3;
618
 
      else if(ts->buf[i+1])
 
625
      if (ts->buf[i+1])
619
626
        i += 2;
620
 
      else if(ts->buf[i])
 
627
      else if (ts->buf[i])
 
628
        i++;
 
629
      else if (ts->buf[i+2] != 1)
621
630
        i++;
622
631
      else
623
632
        break;
650
659
int64_t ts_get_pts(ts_state_t *ts, const uint8_t *data)
651
660
{
652
661
  int64_t pts = NO_PTS;
653
 
  int     cnt = ts_get_pes(ts, data);
 
662
  size_t  cnt = ts_get_pes(ts, data);
654
663
 
655
664
  if (cnt > 14) {
656
665
    pts = pes_get_pts(ts->buf, ts->buf_len);
676
685
 * ts_get_video_size()
677
686
 */
678
687
 
 
688
#include "h264.h"
 
689
#include "mpeg.h"
 
690
 
679
691
int ts_get_video_size(ts_state_t *ts, const uint8_t *data, video_size_t *size, int h264)
680
692
{
 
693
  /* Accumulate data. Skip all data until start code. */
 
694
  if (ts_get_pes(ts, data) < 9)
 
695
    return 0;
 
696
 
 
697
  /* start scanning PES payload */
 
698
  if (!ts->inside_pes) {
 
699
 
 
700
    /* Skip PES header */
 
701
    ts_skip_payload(ts, PES_HEADER_LEN(ts->buf));
 
702
    ts->inside_pes = 1;
 
703
 
 
704
    /* move to first ES header */
 
705
    ts_scan_startcode(ts);
 
706
  }
 
707
 
 
708
  /* scan for start code */
 
709
 
 
710
  while (ts->buf_len > 9) {
 
711
    uint8_t *buf = ts->buf;
 
712
 
 
713
    /* MPEG2 sequence start code */
 
714
    if (h264 != 1 && IS_SC_SEQUENCE(buf)) {
 
715
      if (mpeg2_get_video_size(ts->buf, ts->buf_len, size)) {
 
716
        ts_state_reset(ts);
 
717
        return 1;
 
718
      }
 
719
      if (ts->buf_len < ts->buf_size - TS_SIZE)
 
720
        return 0;
 
721
    }
 
722
 
 
723
    /* H.264 NAL AUD */
 
724
    if (h264 != 0 && IS_NAL_AUD(buf)) {
 
725
      if (h264_get_video_size(ts->buf, ts->buf_len, size)) {
 
726
        ts_state_reset(ts);
 
727
        return 1;
 
728
      }
 
729
      if (ts->buf_len < ts->buf_size - TS_SIZE)
 
730
        return 0;
 
731
    }
 
732
 
 
733
    /* find next start code */
 
734
    ts_skip_payload(ts, 4);
 
735
    ts_scan_startcode(ts);
 
736
  }
 
737
 
681
738
  return 0;
682
739
}