File: pes.h

package info (click to toggle)
vdr-plugin-xineliboutput 2.3.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,476 kB
  • sloc: ansic: 38,688; sh: 438; makefile: 351; cpp: 11
file content (130 lines) | stat: -rw-r--r-- 3,362 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
 * pes.h: PES header definitions
 *
 * See the main source file 'xineliboutput.c' for copyright information and
 * how to reach the author.
 *
 * $Id$
 *
 */

#ifndef _XINELIBOUTPUT_PES_H_
#define _XINELIBOUTPUT_PES_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>

/*
 * Constants
 */

#define PES_CHUNK_SIZE 2048

#define MAX_SCR ((int64_t)0x1ffffffffLL)

#define NO_PTS  (INT64_C(-1))

/* PES PIDs */
#define PRIVATE_STREAM1   0xBD
#define PADDING_STREAM    0xBE
#define PRIVATE_STREAM2   0xBF
#define AUDIO_STREAM_S    0xC0      /* 1100 0000 */
#define AUDIO_STREAM_E    0xDF      /* 1101 1111 */
#define VIDEO_STREAM_S    0xE0      /* 1110 0000 */
#define VIDEO_STREAM_E    0xEF      /* 1110 1111 */

#define AUDIO_STREAM_MASK 0x1F  /* 0001 1111 */
#define VIDEO_STREAM_MASK 0x0F  /* 0000 1111 */
#define AUDIO_STREAM      0xC0  /* 1100 0000 */
#define VIDEO_STREAM      0xE0  /* 1110 0000 */

#define ECM_STREAM        0xF0
#define EMM_STREAM        0xF1
#define DSM_CC_STREAM     0xF2
#define ISO13522_STREAM   0xF3
#define PROG_STREAM_DIR   0xFF

#define IS_VIDEO_PACKET(data)      (VIDEO_STREAM    == ((data)[3] & ~VIDEO_STREAM_MASK))
#define IS_MPEG_AUDIO_PACKET(data) (AUDIO_STREAM    == ((data)[3] & ~AUDIO_STREAM_MASK))
#define IS_PS1_PACKET(data)        (PRIVATE_STREAM1 == (data)[3])
#define IS_PADDING_PACKET(data)    (PADDING_STREAM  == (data)[3])
#define IS_AUDIO_PACKET(data)      (IS_MPEG_AUDIO_PACKET(data) || IS_PS1_PACKET(data))

#define PES_HAS_PTS(data)     ((data)[7] & 0x80)
#define PES_HAS_DTS(data)     ((data)[7] & 0x40)

#define DATA_IS_PES(data) (!(data)[0] && !(data)[1] && (data)[2] == 1)

#define PES_HEADER_LEN(data) (8 + (data)[8] + 1)


/*
 * timestamps
 */

static inline int     pts_to_ms(int64_t pts) { return (int)(pts/INT64_C(90)); }
static inline int64_t ms_to_pts(int ms)      { return ((int64_t)(ms)) * INT64_C(90); }

int64_t pes_get_pts(const uint8_t *buf, int len);
int64_t pes_get_dts(const uint8_t *buf, int len);
void    pes_change_pts(uint8_t *buf, int len, int64_t new_pts);
int     pes_strip_pts_dts(uint8_t *buf, int len);

/*
 * payload
 */

struct video_size_s;

int     pes_is_frame_h264(const uint8_t *buf, int len);
uint8_t pes_get_picture_type(const uint8_t *buf, int len);
int     pes_get_video_size(const uint8_t *buf, int len, struct video_size_s *size, int h264);

static inline int pes_is_mpeg1(const uint8_t *header)
{
  if (IS_VIDEO_PACKET(header) || IS_AUDIO_PACKET(header))
    return ((header[6] & 0xC0) != 0x80);
  if (header[3] == 0xBA) 
    return ((header[4] & 0x40) == 0); /* mpeg1 */
  return 0;
}

/*
 * Extract PES packet length
 */

static inline int pes_packet_len(const uint8_t *data, const int len)
{
  if (IS_VIDEO_PACKET(data) || IS_AUDIO_PACKET(data)) {
    if (len < 6)
      return 0;
    return 6 + (data[4] << 8 | data[5]);
  } else if (data[3] == PADDING_STREAM) {
    if (len < 6)
      return 0;
    return 6 + (data[4] << 8 | data[5]);
  } else if (data[3] == 0xBA) {
    if (len < 5)
      return 0;
    if ((data[4] & 0x40) == 0)  /* mpeg1 */
      return 12;
    else  { /* mpeg 2 */
      if (len < 14)
        return 0;
      return 14 + (data[0xD] & 0x07);
    }
  } else if (data[3] <= 0xB9) {
    return -3;
  }
  return -(6 + (data[4] << 8 | data[5]));
}


#ifdef __cplusplus
} /* extern "C" { */
#endif

#endif /* _XINELIBOUTPUT_PES_H_ */