summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/pes.c157
1 files changed, 157 insertions, 0 deletions
diff --git a/tools/pes.c b/tools/pes.c
new file mode 100644
index 00000000..b2520340
--- /dev/null
+++ b/tools/pes.c
@@ -0,0 +1,157 @@
+/*
+ * pes.h: PES header definitions
+ *
+ * See the main source file 'xineliboutput.c' for copyright information and
+ * how to reach the author.
+ *
+ * $Id: pes.c,v 1.1 2008-02-04 23:46:08 phintuka Exp $
+ *
+ */
+
+#include "mpeg.h"
+#include "h264.h"
+
+#include "pes.h"
+
+
+int64_t pes_get_pts(const uint8_t *buf, int len)
+{
+ /* assume mpeg2 pes header ... */
+
+ if ((VIDEO_STREAM == (buf[3] & ~VIDEO_STREAM_MASK)) ||
+ (AUDIO_STREAM == (buf[3] & ~AUDIO_STREAM_MASK)) ||
+ (PRIVATE_STREAM1 == buf[3])) {
+
+ if ((buf[6] & 0xC0) != 0x80)
+ return INT64_C(-1);
+ if ((buf[6] & 0x30) != 0)
+ return INT64_C(-1);
+
+ if ((len > 14) && (buf[7] & 0x80)) { /* pts avail */
+ int64_t pts;
+ pts = ((int64_t)(buf[ 9] & 0x0E)) << 29 ;
+ pts |= ((int64_t) buf[10]) << 22 ;
+ pts |= ((int64_t)(buf[11] & 0xFE)) << 14 ;
+ pts |= ((int64_t) buf[12]) << 7 ;
+ pts |= ((int64_t)(buf[13] & 0xFE)) >> 1 ;
+ return pts;
+ }
+ }
+ return INT64_C(-1);
+}
+
+int64_t pes_get_dts(const uint8_t *buf, int len)
+{
+ if ((VIDEO_STREAM == (buf[3] & ~VIDEO_STREAM_MASK)) ||
+ (AUDIO_STREAM == (buf[3] & ~AUDIO_STREAM_MASK)) ||
+ (PRIVATE_STREAM1 == buf[3])) {
+
+ if ((buf[6] & 0xC0) != 0x80)
+ return INT64_C(-1);
+ if ((buf[6] & 0x30) != 0)
+ return INT64_C(-1);
+
+ if (len > 18 && (buf[7] & 0x40)) { /* dts avail */
+ int64_t dts;
+ dts = ((int64_t)( buf[14] & 0x0E)) << 29 ;
+ dts |= (int64_t)( buf[15] << 22 );
+ dts |= (int64_t)((buf[16] & 0xFE) << 14 );
+ dts |= (int64_t)( buf[17] << 7 );
+ dts |= (int64_t)((buf[18] & 0xFE) >> 1 );
+ return dts;
+ }
+ }
+ return INT64_C(-1);
+}
+
+void pes_change_pts(uint8_t *buf, int len, int64_t new_pts)
+{
+ /* assume mpeg2 pes header ... Assume header already HAS pts */
+ if (IS_VIDEO_PACKET(buf) || IS_AUDIO_PACKET(buf)) {
+
+ if ((buf[6] & 0xC0) != 0x80)
+ return;
+ if ((buf[6] & 0x30) != 0)
+ return;
+
+ if ((len > 14) && (buf[7] & 0x80)) { /* pts avail */
+ buf[ 9] = ((new_pts >> 29) & 0x0E) | (buf[ 9] & 0xf1);
+ buf[10] = ((new_pts >> 22) & 0xFF);
+ buf[11] = ((new_pts >> 14) & 0xFE) | (buf[11] & 0x01);
+ buf[12] = ((new_pts >> 7 ) & 0xFF);
+ buf[13] = ((new_pts << 1 ) & 0xFE) | (buf[13] & 0x01);
+ }
+ }
+}
+
+int pes_strip_pts_dts(uint8_t *buf, int size)
+{
+ if(size > 13 && buf[7] & 0x80) { /* pts avail */
+ int n = 5;
+ int pes_len = (buf[4] << 8) | buf[5];
+ if ((buf[6] & 0xC0) != 0x80)
+ return size;
+ if ((buf[6] & 0x30) != 0) /* scrambling control */
+ return size;
+ /* dts too ? */
+ if(size > 18 && buf[7] & 0x40)
+ n += 5;
+ pes_len -= n; /* update packet len */
+ buf[4] = pes_len >> 8; /* packet len (hi) */
+ buf[5] = pes_len & 0xff; /* packet len (lo) */
+ buf[7] &= 0x7f; /* clear pts flag */
+ buf[8] -= 5; /* update header len */
+ memmove(buf+4+n, buf+9+n, size-9-n);
+ return size - n;
+ }
+ return size;
+}
+
+int pes_is_frame_h264(const uint8_t *buf, int len)
+{
+ if (len < 9 || len < 9 + buf[8])
+ return 0;
+ if ( (buf[6] & 0xC0) != 0x80) /* MPEG 2 PES */
+ return 0;
+
+ buf += 9 + buf[8];
+
+ if (!buf[0] && !buf[1] && buf[2] == 0x01 && buf[3] == 0x09)
+ return 1;
+ return 0;
+}
+
+uint8_t pes_get_picture_type(const uint8_t *buf, int len)
+{
+ int i = 8; /* the minimum length of the video packet header */
+ i += buf[i] + 1; /* possible additional header bytes */
+
+ buf += i;
+ len -= i;
+
+ if (!buf[0] && !buf[1] && buf[2]) {
+ if (buf[3] == 0x09)
+ return h264_get_picture_type(buf, len);
+ else
+ return mpeg2_get_picture_type(buf, len);
+ }
+ return NO_PICTURE;
+}
+
+int pes_get_video_size(const uint8_t *buf, int len, video_size_t *size, int h264)
+{
+ int i = 8;
+
+ i += buf[i] + 1; /* possible additional header bytes */
+
+ buf += i;
+ len -= i;
+
+ if (h264 || (!buf[0] && !buf[1] && buf[2] == 0x01 && buf[3] == 0x09))
+ return h264_get_video_size(buf, len, size);
+ else
+ return mpeg2_get_video_size(buf, len, size);
+
+ return 0;
+}
+