summaryrefslogtreecommitdiff
path: root/remux/tsremux.c
diff options
context:
space:
mode:
authorFrank Schmirler <schmirl@puter.linogate.de>2010-12-02 08:53:01 +0100
committerFrank Schmirler <schmirl@puter.linogate.de>2010-12-02 08:53:01 +0100
commit5e30711bfdb28085234a5ef6da4f4e44305ac3e4 (patch)
treed15809d23eeeed7fda55d9450b1af7c99d6eb5d6 /remux/tsremux.c
downloadvdr-plugin-streamdev-5e30711bfdb28085234a5ef6da4f4e44305ac3e4.tar.gz
vdr-plugin-streamdev-5e30711bfdb28085234a5ef6da4f4e44305ac3e4.tar.bz2
Snapshot 2007-03-20
Diffstat (limited to 'remux/tsremux.c')
-rw-r--r--remux/tsremux.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/remux/tsremux.c b/remux/tsremux.c
new file mode 100644
index 0000000..6be5245
--- /dev/null
+++ b/remux/tsremux.c
@@ -0,0 +1,59 @@
+#include "remux/tsremux.h"
+
+#define SC_PICTURE 0x00 // "picture header"
+
+void cTSRemux::SetBrokenLink(uchar *Data, int Length)
+{
+ if (Length > 9 && Data[0] == 0 && Data[1] == 0 && Data[2] == 1 && (Data[3] & 0xF0) == VIDEO_STREAM_S) {
+ for (int i = Data[8] + 9; i < Length - 7; i++) { // +9 to skip video packet header
+ if (Data[i] == 0 && Data[i + 1] == 0 && Data[i + 2] == 1 && Data[i + 3] == 0xB8) {
+ if (!(Data[i + 7] & 0x40)) // set flag only if GOP is not closed
+ Data[i + 7] |= 0x20;
+ return;
+ }
+ }
+ dsyslog("SetBrokenLink: no GOP header found in video packet");
+ }
+ else
+ dsyslog("SetBrokenLink: no video packet in frame");
+}
+
+int cTSRemux::GetPid(const uchar *Data)
+{
+ return (((uint16_t)Data[0] & PID_MASK_HI) << 8) | (Data[1] & 0xFF);
+}
+
+int cTSRemux::GetPacketLength(const uchar *Data, int Count, int Offset)
+{
+ // Returns the length of the packet starting at Offset, or -1 if Count is
+ // too small to contain the entire packet.
+ int Length = (Offset + 5 < Count) ? (Data[Offset + 4] << 8) + Data[Offset + 5] + 6 : -1;
+ if (Length > 0 && Offset + Length <= Count)
+ return Length;
+ return -1;
+}
+
+int cTSRemux::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 = GetPacketLength(Data, Count, Offset);
+ if (Length > 0) {
+ if (Length >= 8) {
+ int i = Offset + 8; // the minimum length of the video packet header
+ i += Data[i] + 1; // possible additional header bytes
+ for (; i < Offset + 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;
+}
+