-
Notifications
You must be signed in to change notification settings - Fork 6
/
mpegts.hpp
executable file
·121 lines (94 loc) · 3.55 KB
/
mpegts.hpp
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/**
* @file mpegts.hpp
* @brief Parses programs and elementary streams from a MPEG Transport
* stream.
*
* @copyright Copyright 2015 Samir Sinha. All rights reserved.
* @license This project is released under the ISC license. See LICENSE
* for the full text.
*/
#ifndef CINEK_AVLIB_MPEG2TS_HPP
#define CINEK_AVLIB_MPEG2TS_HPP
#include "avlib.hpp"
#include "elemstream.hpp"
#include <functional>
#if CINEK_AVLIB_IOSTREAMS
#include <istream>
#endif
namespace cinekav {
class ElementaryStream;
}
namespace cinekav { namespace mpegts {
constexpr int kDefaultPacketSize = 188;
constexpr uint16_t kPID_PAT = 0x0000;
constexpr uint16_t kPID_Null = 0x1fff;
constexpr uint8_t kPAT_Program_Assoc_Table = 0x00;
constexpr uint8_t kPAT_Program_Map_Table = 0x02;
class Demuxer
{
public:
/// Result Codes
enum Result
{
kComplete,
kTruncated,
kInvalidPacket,
kContinue,
kIOError,
kOutOfMemory,
kStreamOverflow, ///< Output ES overflow detected
kUnsupportedTable, ///< PSI table type is not supported
kUnsupported, ///< Feature within the TS is unsupported
kInternalError ///< Unknown (internal) error
};
using CreateStreamFn =
std::function<cinekav::ElementaryStream*(cinekav::ElementaryStream::Type,
uint16_t programId)>;
using GetStreamFn =
std::function<cinekav::ElementaryStream*(uint16_t programId,
uint16_t index)>;
using FinalizeStreamFn =
std::function<void(uint16_t programId, uint16_t index)>;
using OverflowStreamFn =
std::function<cinekav::ElementaryStream*(uint16_t programId,
uint16_t index,
uint32_t len)>;
Demuxer(const CreateStreamFn& createStreamFn,
const GetStreamFn& getStreamFn,
const FinalizeStreamFn& finalStreamFn,
const OverflowStreamFn& overflowStreamFn,
const Memory& memory =Memory());
~Demuxer();
#if CINEK_AVLIB_IOSTREAMS
Result read(std::basic_istream<char>& istr);
#endif
Result read(Buffer& buffer);
void reset();
private:
Result readInternal(const std::function<int(Buffer&)>& inFn);
// buffer state
Memory _memory;
Buffer _buffer;
CreateStreamFn _createStreamFn;
GetStreamFn _getStreamFn;
FinalizeStreamFn _finalStreamFn;
OverflowStreamFn _overflowStreamFn;
// sorted list of buffers (sorted by PID)
struct BufferNode;
BufferNode* _headBuffer;
// tracks the current state of parsing
int _syncCnt;
int _skipCnt;
private:
Result readInternal();
void finalizeStreams();
Result parsePacket();
Result parsePayloadPSI(BufferNode& bufferNode, bool start);
Result parseSectionPAT(BufferNode& bufferNode);
Result parseSectionPMT(BufferNode& bufferNode, uint16_t programId);
Result parsePayloadPES(BufferNode& bufferNode, bool start);
uint64_t pullTimecodeFromBuffer(Buffer& buffer);
BufferNode* createOrFindBuffer(uint16_t pid);
};
} /* namespace mpegts */ } /* namespace ckavlib */
#endif