summaryrefslogtreecommitdiff
path: root/command/pes2es.cpp
blob: d0287d0967ef1125766ca9dda2f96ee67afe4412 (plain)
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
/*
 * pes2es.cpp: A program for the Video Disk Recorder
 *
 * See the README file for copyright information and how to reach the author.
 *
 */

#include <inttypes.h>
#include <stdlib.h>
#include <string.h>

#include "pes2es.h"

cMarkAdPES2ES::cMarkAdPES2ES(const char *QueueName, int QueueSize)
{
    queue = new cMarkAdPaketQueue(QueueName,QueueSize);
    type=0;
}

cMarkAdPES2ES::~cMarkAdPES2ES()
{
    if (queue) delete queue;
}

void cMarkAdPES2ES::Clear()
{
    if (queue) queue->Clear();
}

void cMarkAdPES2ES::Process(MarkAdPid Pid, uchar *PESData, int PESSize, uchar **ESData, int *ESSize)
{
    if ((!ESData) || (!ESSize) || (!queue)) return;
    *ESData=NULL;
    *ESSize=0;

    if (PESData)
    {
        struct PESHDR *peshdr=(struct PESHDR *) PESData;

        // first check some simple things
        if ((peshdr->Sync1!=0) && (peshdr->Sync2!=0) && (peshdr->Sync3!=1))
        {
            Clear();
            return;
        }

        if (peshdr->StreamID<=0xBC) return;

        int Length=(peshdr->LenH<<8)+peshdr->LenL;
        if (Length) Length+=sizeof(PESHDR);
        if (Length!=PESSize)
        {
            if ((peshdr->StreamID & 0xF0)==0xE0) return;
            Clear();
            return;
        }

        switch (Pid.Type)
        {
        case MARKAD_PIDTYPE_VIDEO_H262:
            if ((peshdr->StreamID & 0xF0)!=0xE0) return;
            type=MA_PACKET_PKT;
            break;
        case MARKAD_PIDTYPE_VIDEO_H264:
            if ((peshdr->StreamID & 0xF0)!=0xE0) return;
            type=MA_PACKET_H264;
            break;
        case MARKAD_PIDTYPE_AUDIO_AC3:
            if (peshdr->StreamID!=0xBD) return;
            type=MA_PACKET_AC3;
            break;
        case MARKAD_PIDTYPE_AUDIO_MP2:
            if ((peshdr->StreamID<0xC0) || (peshdr->StreamID>0xDF)) return;
            type=MA_PACKET_MP2;
            break;
        default:
            Clear();
            return;
        }

        struct PESHDROPT *peshdropt=(struct PESHDROPT *) &PESData[sizeof(struct PESHDR)];

        uchar *buf;
        int buflen;

        if (peshdropt->MarkerBits==0x2)
        {
            // we have an optional PES header
            int bpos=sizeof(struct PESHDR)+sizeof(struct PESHDROPT)+
                     peshdropt->Length;
            buf=&PESData[bpos];
            buflen=PESSize-bpos;
        }
        else
        {
            int bpos=sizeof(struct PESHDR);
            buf=&PESData[bpos];
            buflen=PESSize-bpos;
        }
        queue->Put(buf,buflen);
    }
    if (type) *ESData=queue->GetPacket(ESSize,type);
    return;
}