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_ */
|