diff options
author | phintuka <phintuka> | 2008-02-04 23:59:30 +0000 |
---|---|---|
committer | phintuka <phintuka> | 2008-02-04 23:59:30 +0000 |
commit | 20c9e9f0a8552a27cf7252e5c872120f757acb9e (patch) | |
tree | 499f2ba1f542ad53c8f1ebb734381b54b0e4d531 | |
parent | 537b528c9fcd48e90a96d84bcdf4329f3cb51f94 (diff) | |
download | xineliboutput-20c9e9f0a8552a27cf7252e5c872120f757acb9e.tar.gz xineliboutput-20c9e9f0a8552a27cf7252e5c872120f757acb9e.tar.bz2 |
Split to pes.h, mpeg.h and h264.h
Move (most) code to pes.c, mpeg.c and h264.c
Convert file to plain C so it can be used in xine_input_vdr.c
-rw-r--r-- | tools/pes.h | 298 |
1 files changed, 47 insertions, 251 deletions
diff --git a/tools/pes.h b/tools/pes.h index 4cb3abef..c55a4ed5 100644 --- a/tools/pes.h +++ b/tools/pes.h @@ -4,22 +4,25 @@ * See the main source file 'xineliboutput.c' for copyright information and * how to reach the author. * - * $Id: pes.h,v 1.5 2008-01-24 08:33:59 phintuka Exp $ + * $Id: pes.h,v 1.6 2008-02-04 23:59:30 phintuka Exp $ * */ #ifndef _PES_H_ #define _PES_H_ -// -// Constants -// +#include "mpeg.h" + + +/* + * Constants + */ #define PES_CHUNK_SIZE 2048 #define MAX_SCR ((int64_t)0x1ffffffffLL) -// PES PIDs +/* PES PIDs */ #define PRIVATE_STREAM1 0xBD #define PADDING_STREAM 0xBE #define PRIVATE_STREAM2 0xBF @@ -39,267 +42,60 @@ #define ISO13522_STREAM 0xF3 #define PROG_STREAM_DIR 0xFF -// "picture header" -#define SC_PICTURE 0x00 - -// Picture types -#define NO_PICTURE 0 -#define I_FRAME 1 -#define P_FRAME 2 -#define B_FRAME 3 +#define IS_VIDEO_PACKET(data) (VIDEO_STREAM == ((data)[3] & ~VIDEO_STREAM_MASK)) +#define IS_AUDIO_PACKET(data) ((AUDIO_STREAM == ((data)[3] & ~AUDIO_STREAM_MASK)) || \ + (PRIVATE_STREAM1 == (data)[3])) -// -// Extract PTS from PES packet -// +#define PES_HAS_PTS(data) ((data)[7] & 0x80) +#define PES_HAS_DTS(data) ((data)[7] & 0x40) -static inline int64_t pes_extract_pts(const uchar *Data, int Length, - bool& Audio, bool& Video) -{ - /* assume mpeg2 pes header ... */ - Audio = Video = false; +/* + * timestamps + */ - if((VIDEO_STREAM == (Data[3] & ~VIDEO_STREAM_MASK) && (Video=true)) || - (AUDIO_STREAM == (Data[3] & ~AUDIO_STREAM_MASK) && (Audio=true)) || - (PRIVATE_STREAM1 == Data[3] && (Audio=true))) { - - if ((Data[6] & 0xC0) != 0x80) - return -1; - if ((Data[6] & 0x30) != 0) - return -1; - - if((Length > 14) && (Data[7] & 0x80)) { /* pts avail */ - int64_t pts; - pts = ((int64_t)(Data[ 9] & 0x0E)) << 29 ; - pts |= ((int64_t) Data[10]) << 22 ; - pts |= ((int64_t)(Data[11] & 0xFE)) << 14 ; - pts |= ((int64_t) Data[12]) << 7 ; - pts |= ((int64_t)(Data[13] & 0xFE)) >> 1 ; - return pts; - } - } - return -1ULL; -} -// -// Change PTS of PES packet -// +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); -static inline void pes_change_pts(uchar *Data, int Length, int64_t pts) -{ - /* assume mpeg2 pes header ... Assume header already HAS pts */ - if((VIDEO_STREAM == (Data[3] & ~VIDEO_STREAM_MASK)) || - (AUDIO_STREAM == (Data[3] & ~AUDIO_STREAM_MASK)) || - (PRIVATE_STREAM1 == Data[3])) { - - if ((Data[6] & 0xC0) != 0x80) - return; - if ((Data[6] & 0x30) != 0) - return; - - if((Length > 14) && (Data[7] & 0x80)) { /* pts avail */ - Data[ 9] = ((pts >> 29) & 0x0E) | (Data[ 9] & 0xf1); - Data[10] = ((pts >> 22) & 0xFF); - Data[11] = ((pts >> 14) & 0xFE) | (Data[11] & 0x01); - Data[12] = ((pts >> 7 ) & 0xFF); - Data[13] = ((pts << 1 ) & 0xFE) | (Data[13] & 0x01); - } - } -} +/* + * payload + */ -// -// Remove pts from PES packet (set to 0LL) -// +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, video_size_t *size, int h264); -static inline void pes_strip_pts(uchar *Data, int Len) +static inline int pes_is_mpeg1(const uint8_t *header) { - if(VIDEO_STREAM == (Data[3] & ~VIDEO_STREAM_MASK) || - AUDIO_STREAM == (Data[3] & ~AUDIO_STREAM_MASK) || - PRIVATE_STREAM1 == Data[3]) { - - // MPEG1 PES - if ((Data[6] & 0xC0) != 0x80) { - Data += 6; - Len -= 6; - - // skip stuffing - while ((Data[0] & 0x80) == 0x80) { - Data++; - Len--; - } - if ((Data[0] & 0xc0) == 0x40) { - // STD_buffer_scale, STD_buffer_size - Data += 2; - Len -= 2; - } - - if(Len<5) return; - if ((Data[0] & 0xf0) == 0x20) { - // zero PTS - Data[0] &= ~0x0E; - Data[1] = 0; - Data[2] &= ~0xFE; - Data[3] = 0; - Data[4] &= ~0xFE; - return; - } - if(Len<10) return; - if ((Data[0] & 0xf0) == 0x30) { - // zero PTS & DTS -//((uint32*)Data)[0] &= 0x0E00FE00; - Data[0] &= ~0x0E; - Data[1] = 0; - Data[2] &= ~0xFE; - Data[3] = 0; -//((uint32*)Data)[1] &= 0xFE0E00FE; - Data[4] &= ~0xFE; - Data[5] &= ~0x0E; - Data[6] = 0; - Data[7] &= ~0xFE; -//((uint32*)Data)[2] &= 0x00FEFFFF; - Data[8] = 0; - Data[9] &= ~0xFE; - return; - } - - // MPEG2 PES - } else { - if ((Data[6] & 0xC0) != 0x80) - return; - if ((Data[6] & 0x30) != 0) - return; - - if(Len<14) return; - if (Data[7] & 0x80) { - // PTS - if(Data[8]<5) return; - Data[ 9] &= ~0x0E; - Data[10] = 0; - Data[11] &= ~0xFE; - Data[12] = 0; - Data[13] &= ~0xFE; - } - if(Len<19) return; - if (Data[7] & 0x40) { - // DTS - if(Data[8]<10) return; - Data[14] &= ~0x0E; - Data[15] = 0; - Data[16] &= ~0xFE; - Data[17] = 0; - Data[18] &= ~0xFE; - } - } - } + 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 -// +/* + * Extract PES packet length + */ -static inline int pes_packet_len(const uchar *header, const int maxlen, bool &isMpeg1) +static inline int pes_packet_len(const uint8_t *data, const int len) { - if(VIDEO_STREAM == (header[3] & ~VIDEO_STREAM_MASK) || - AUDIO_STREAM == (header[3] & ~AUDIO_STREAM_MASK) || - PRIVATE_STREAM1 == header[3]) { - isMpeg1 = ((header[6] & 0xC0) != 0x80); - return 6 + (header[4] << 8 | header[5]); - } else if (header[3] == PADDING_STREAM) { - isMpeg1 = false; - return (6 + (header[4] << 8 | header[5])); - } else if (header[3] == 0xBA) { - if ((header[4] & 0x40) == 0) { /* mpeg1 */ - isMpeg1 = true; + if (IS_VIDEO_PACKET(data) || IS_AUDIO_PACKET(data)) { + return 6 + (data[4] << 8 | data[5]); + } else if (data[3] == PADDING_STREAM) { + return 6 + (data[4] << 8 | data[5]); + } else if (data[3] == 0xBA) { + if ((data[4] & 0x40) == 0) /* mpeg1 */ return 12; - } else { /* mpeg 2 */ - isMpeg1 = false; - return 14 + (header[0xD] & 0x07); - } - } else if (header[3] <= 0xB9) { - int len=3; + else /* mpeg 2 */ + return 14 + (data[0xD] & 0x07); + } else if (data[3] <= 0xB9) { return -3; - isMpeg1 = false; - while(len+2<maxlen) { - if(!header[len] && !header[len+1] && header[len+2] == 1) - return len; - len++; - } - return -len; - } - isMpeg1 = false; - return -(6 + (header[4] << 8 | header[5])); -} - -// -// Extract video frame size from video PES packet -// - returns 1 if size was found -// - -static inline int GetVideoSize(const uchar *buf, int length, int *width, int *height) -{ - int i = 8; // the minimum length of the video packet header - i += buf[i] + 1; // possible additional header bytes - for (; i < length-6; i++) { - if (buf[i] == 0 && buf[i + 1] == 0 && buf[i + 2] == 1) { - if(buf[i + 3] == 0xb3) { - int d = (buf[i+4] << 16) | (buf[i+5] << 8) | buf[i+6]; - *width = (d >> 12); - *height = (d & 0xfff); - return 1; - } - } - } - return 0; -} - -static inline bool IsFrameH264(const uchar *Data, int Count) -{ - if (Count < 9 || Count < 9 + Data[8]) - return false; - if ( (Data[6] & 0xC0) != 0x80) /* MPEG 2 */ - return false; - - Data += 9 + Data[8]; - - if (!Data[0] && !Data[1] && Data[2] == 0x01 && Data[3] == 0x09) - return true; - return false; -} - -// from vdr/remux.c: -static inline int ScanVideoPacket(const uchar *Data, int Count, /*int Offset,*/ - uchar &PictureType) -{ - // Scans the video packet starting at Offset and returns its length. - // If the return value is -1 the packet was not completely in the buffer. - int Length = Count; - if (Length > 0 && Length <= Count) { - int i = 8; // the minimum length of the video packet header - i += Data[i] + 1; // possible additional header bytes - for (; i < Length-5; i++) { - if (Data[i] == 0 && Data[i + 1] == 0 && Data[i + 2] == 1) { - switch (Data[i + 3]) { - case SC_PICTURE: - PictureType = (Data[i + 5] >> 3) & 0x07; - return Length; - } - } - } - PictureType = NO_PICTURE; - return Length; } - return -1; + return -(6 + (data[4] << 8 | data[5])); } -static inline const char *PictureTypeStr(int Type) -{ - switch(Type) { - case I_FRAME: return "I-Frame"; break; - case B_FRAME: return "B-Frame"; break; - case P_FRAME: return "P-Frame"; break; - case NO_PICTURE: return "(none)"; break; - default: break; - } - return "UNKNOWN"; -} -#endif +#endif /* _PES_H_ */ |