@@ -11,6 +11,8 @@ CServiceFilter::CServiceFilter()
11
11
, m_audio1MuxDualMono(false )
12
12
, m_captionMode(0 )
13
13
, m_superimposeMode(0 )
14
+ , m_captionInsertManagementPacket(false )
15
+ , m_superimposeInsertManagementPacket(false )
14
16
, m_videoPid(0 )
15
17
, m_audio1Pid(0 )
16
18
, m_audio2Pid(0 )
@@ -24,11 +26,15 @@ CServiceFilter::CServiceFilter()
24
26
, m_pmtCounter(0 )
25
27
, m_audio1PesCounter(0 )
26
28
, m_audio2PesCounter(0 )
29
+ , m_captionPesCounter(0xff )
30
+ , m_superimposePesCounter(0xff )
27
31
, m_isAudio1DualMono(false )
28
32
, m_audio1Pts(-1 )
29
33
, m_audio2Pts(-1 )
30
34
, m_audio1PtsPcrDiff(0 )
31
35
, m_audio2PtsPcrDiff(-1 )
36
+ , m_captionManagementPcr(-1 )
37
+ , m_superimposeManagementPcr(-1 )
32
38
{
33
39
static const PAT zeroPat = {};
34
40
m_pat = zeroPat;
@@ -48,6 +54,18 @@ void CServiceFilter::SetAudio2Mode(int mode)
48
54
m_audio2MuxToStereo = !!(mode & 4 );
49
55
}
50
56
57
+ void CServiceFilter::SetCaptionMode (int mode)
58
+ {
59
+ m_captionMode = mode % 4 ;
60
+ m_captionInsertManagementPacket = !!(mode & 4 );
61
+ }
62
+
63
+ void CServiceFilter::SetSuperimposeMode (int mode)
64
+ {
65
+ m_superimposeMode = mode % 4 ;
66
+ m_superimposeInsertManagementPacket = !!(mode & 4 );
67
+ }
68
+
51
69
void CServiceFilter::AddPacket (const uint8_t *packet)
52
70
{
53
71
if (m_programNumberOrIndex == 0 ) {
@@ -118,6 +136,39 @@ void CServiceFilter::AddPacket(const uint8_t *packet)
118
136
}
119
137
AddAudioPesPackets (1 , (m_pcr + m_audio2PtsPcrDiff) & 0x1ffffffff , m_audio2Pts, m_audio2PesCounter);
120
138
}
139
+
140
+ static const int INSERT_MANAGEMENT_DETERMINE_ABSENCE_SEC = 15 ;
141
+ static const int INSERT_MANAGEMENT_INTERVAL_SEC = INSERT_MANAGEMENT_DETERMINE_ABSENCE_SEC - 5 ;
142
+ if (m_captionManagementPcr >= 0 &&
143
+ m_captionInsertManagementPacket &&
144
+ (m_captionPid != 0 || m_captionMode == 1 )) {
145
+ int64_t pcrDiff = (0x200000000 + m_pcr - m_captionManagementPcr) & 0x1ffffffff ;
146
+ if (pcrDiff > 90000 * INSERT_MANAGEMENT_DETERMINE_ABSENCE_SEC) {
147
+ if (pcrDiff < 90000 * INSERT_MANAGEMENT_DETERMINE_ABSENCE_SEC * 2 ) {
148
+ m_captionPesCounter = (m_captionPesCounter + 1 ) & 0x0f ;
149
+ AddCaptionManagementPesPacket (m_pcr, m_captionPesCounter);
150
+ }
151
+ m_captionManagementPcr = (0x200000000 + m_pcr - 90000 * INSERT_MANAGEMENT_INTERVAL_SEC) & 0x1ffffffff ;
152
+ }
153
+ }
154
+ else {
155
+ m_captionManagementPcr = m_pcr;
156
+ }
157
+ if (m_superimposeManagementPcr >= 0 &&
158
+ m_superimposeInsertManagementPacket &&
159
+ (m_superimposePid != 0 || m_superimposeMode == 1 )) {
160
+ int64_t pcrDiff = (0x200000000 + m_pcr - m_superimposeManagementPcr) & 0x1ffffffff ;
161
+ if (pcrDiff > 90000 * INSERT_MANAGEMENT_DETERMINE_ABSENCE_SEC) {
162
+ if (pcrDiff < 90000 * INSERT_MANAGEMENT_DETERMINE_ABSENCE_SEC * 2 ) {
163
+ m_superimposePesCounter = (m_superimposePesCounter + 1 ) & 0x0f ;
164
+ AddSuperimposeManagementPesPacket (m_superimposePesCounter);
165
+ }
166
+ m_superimposeManagementPcr = (0x200000000 + m_pcr - 90000 * INSERT_MANAGEMENT_INTERVAL_SEC) & 0x1ffffffff ;
167
+ }
168
+ }
169
+ else {
170
+ m_superimposeManagementPcr = m_pcr;
171
+ }
121
172
}
122
173
}
123
174
}
@@ -195,10 +246,14 @@ void CServiceFilter::AddPacket(const uint8_t *packet)
195
246
}
196
247
}
197
248
else if (pid == m_captionPid) {
198
- ChangePidAndAddPacket (packet, 0x0130 );
249
+ m_captionManagementPcr = m_pcr;
250
+ m_captionPesCounter = m_captionPesCounter > 0x0f ? 0x10 | (counter & 0x0f ) : (m_captionPesCounter + 1 ) & 0x0f ;
251
+ ChangePidAndAddPacket (packet, 0x0130 , m_captionPesCounter & 0x0f );
199
252
}
200
253
else if (pid == m_superimposePid) {
201
- ChangePidAndAddPacket (packet, 0x0138 );
254
+ m_superimposeManagementPcr = m_pcr;
255
+ m_superimposePesCounter = m_superimposePesCounter > 0x0f ? 0x10 | (counter & 0x0f ) : (m_superimposePesCounter + 1 ) & 0x0f ;
256
+ ChangePidAndAddPacket (packet, 0x0138 , m_superimposePesCounter & 0x0f );
202
257
}
203
258
else if (pid < 0x0030 ) {
204
259
m_packets.insert (m_packets.end (), packet, packet + 188 );
@@ -604,6 +659,67 @@ void CServiceFilter::ChangePidAndAddPacket(const uint8_t *packet, int pid, uint8
604
659
m_packets.insert (m_packets.end (), packet + 4 , packet + 188 );
605
660
}
606
661
662
+ void CServiceFilter::AddCaptionManagementPesPacket (int64_t pts, uint8_t counter)
663
+ {
664
+ static const uint8_t SYNCHRONOUS_PES_JPN_MANAGEMENT[20 ] = {
665
+ 0x80 , 0xff , 0xf0 , 0x80 , 0x00 , 0x00 , 0x00 , 0x0a ,
666
+ 0x3f , 0x01 , 0x1a , 0x6a , 0x70 , 0x6e , 0x80 , 0x00 , 0x00 , 0x00 ,
667
+ 0xe4 , 0x6a
668
+ };
669
+ m_packets.push_back (0x47 );
670
+ // PID=0x0130
671
+ m_packets.push_back (0x41 );
672
+ m_packets.push_back (0x30 );
673
+ m_packets.push_back (0x30 | counter);
674
+ m_packets.push_back (188 - 5 - (6 + 28 ));
675
+ m_packets.push_back (0x00 );
676
+ // stuffing
677
+ m_packets.resize (m_packets.size () + 188 - 6 - (6 + 28 ), 0xff );
678
+ // PES
679
+ m_packets.push_back (0 );
680
+ m_packets.push_back (0 );
681
+ m_packets.push_back (1 );
682
+ m_packets.push_back (0xbd );
683
+ m_packets.push_back (0 );
684
+ m_packets.push_back (28 );
685
+ m_packets.push_back (0x80 );
686
+ // has PTS
687
+ m_packets.push_back (0x80 );
688
+ m_packets.push_back (5 );
689
+ m_packets.push_back (static_cast <uint8_t >(pts >> 29 ) | 0x21 ); // 3 bits
690
+ m_packets.push_back (static_cast <uint8_t >(pts >> 22 )); // 8 bits
691
+ m_packets.push_back (static_cast <uint8_t >(pts >> 14 ) | 1 ); // 7 bits
692
+ m_packets.push_back (static_cast <uint8_t >(pts >> 7 )); // 8 bits
693
+ m_packets.push_back (static_cast <uint8_t >(pts << 1 ) | 1 ); // 7 bits
694
+ m_packets.insert (m_packets.end (), SYNCHRONOUS_PES_JPN_MANAGEMENT, SYNCHRONOUS_PES_JPN_MANAGEMENT + 20 );
695
+ }
696
+
697
+ void CServiceFilter::AddSuperimposeManagementPesPacket (uint8_t counter)
698
+ {
699
+ static const uint8_t ASYNCHRONOUS_PES_JPN_MANAGEMENT[20 ] = {
700
+ 0x81 , 0xff , 0xf0 , 0x00 , 0x00 , 0x00 , 0x00 , 0x0a ,
701
+ 0x3f , 0x01 , 0x12 , 0x6a , 0x70 , 0x6e , 0x80 , 0x00 , 0x00 , 0x00 ,
702
+ 0xae , 0xa2
703
+ };
704
+ m_packets.push_back (0x47 );
705
+ // PID=0x0138
706
+ m_packets.push_back (0x41 );
707
+ m_packets.push_back (0x38 );
708
+ m_packets.push_back (0x30 | counter);
709
+ m_packets.push_back (188 - 5 - (6 + 20 ));
710
+ m_packets.push_back (0x00 );
711
+ // stuffing
712
+ m_packets.resize (m_packets.size () + 188 - 6 - (6 + 20 ), 0xff );
713
+ // PES
714
+ m_packets.push_back (0 );
715
+ m_packets.push_back (0 );
716
+ m_packets.push_back (1 );
717
+ m_packets.push_back (0xbf );
718
+ m_packets.push_back (0 );
719
+ m_packets.push_back (20 );
720
+ m_packets.insert (m_packets.end (), ASYNCHRONOUS_PES_JPN_MANAGEMENT, ASYNCHRONOUS_PES_JPN_MANAGEMENT + 20 );
721
+ }
722
+
607
723
void CServiceFilter::AddAudioPesPackets (uint8_t index, int64_t targetPts, int64_t &pts, uint8_t &counter)
608
724
{
609
725
static const int ACCEPTABLE_PTS_DIFF_SEC = 10 ;
0 commit comments