#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; }