1 //<MStar Software>
2 //******************************************************************************
3 // MStar Software
4 // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5 // All software, firmware and related documentation herein ("MStar Software") are
6 // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7 // law, including, but not limited to, copyright law and international treaties.
8 // Any use, modification, reproduction, retransmission, or republication of all
9 // or part of MStar Software is expressly prohibited, unless prior written
10 // permission has been granted by MStar.
11 //
12 // By accessing, browsing and/or using MStar Software, you acknowledge that you
13 // have read, understood, and agree, to be bound by below terms ("Terms") and to
14 // comply with all applicable laws and regulations:
15 //
16 // 1. MStar shall retain any and all right, ownership and interest to MStar
17 // Software and any modification/derivatives thereof.
18 // No right, ownership, or interest to MStar Software and any
19 // modification/derivatives thereof is transferred to you under Terms.
20 //
21 // 2. You understand that MStar Software might include, incorporate or be
22 // supplied together with third party`s software and the use of MStar
23 // Software may require additional licenses from third parties.
24 // Therefore, you hereby agree it is your sole responsibility to separately
25 // obtain any and all third party right and license necessary for your use of
26 // such third party`s software.
27 //
28 // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29 // MStar`s confidential information and you agree to keep MStar`s
30 // confidential information in strictest confidence and not disclose to any
31 // third party.
32 //
33 // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34 // kind. Any warranties are hereby expressly disclaimed by MStar, including
35 // without limitation, any warranties of merchantability, non-infringement of
36 // intellectual property rights, fitness for a particular purpose, error free
37 // and in conformity with any international standard. You agree to waive any
38 // claim against MStar for any loss, damage, cost or expense that you may
39 // incur related to your use of MStar Software.
40 // In no event shall MStar be liable for any direct, indirect, incidental or
41 // consequential damages, including without limitation, lost of profit or
42 // revenues, lost or damage of data, and unauthorized system use.
43 // You agree that this Section 4 shall still apply without being affected
44 // even if MStar Software has been modified by MStar in accordance with your
45 // request or instruction for your use, except otherwise agreed by both
46 // parties in writing.
47 //
48 // 5. If requested, MStar may from time to time provide technical supports or
49 // services in relation with MStar Software to you for your use of
50 // MStar Software in conjunction with your or your customer`s product
51 // ("Services").
52 // You understand and agree that, except otherwise agreed by both parties in
53 // writing, Services are provided on an "AS IS" basis and the warranty
54 // disclaimer set forth in Section 4 above shall apply.
55 //
56 // 6. Nothing contained herein shall be construed as by implication, estoppels
57 // or otherwise:
58 // (a) conferring any license or right to use MStar name, trademark, service
59 // mark, symbol or any other identification;
60 // (b) obligating MStar or any of its affiliates to furnish any person,
61 // including without limitation, you and your customers, any assistance
62 // of any kind whatsoever, or any information; or
63 // (c) conferring any license or right under any intellectual property right.
64 //
65 // 7. These terms shall be governed by and construed in accordance with the laws
66 // of Taiwan, R.O.C., excluding its conflict of law rules.
67 // Any and all dispute arising out hereof or related hereto shall be finally
68 // settled by arbitration referred to the Chinese Arbitration Association,
69 // Taipei in accordance with the ROC Arbitration Law and the Arbitration
70 // Rules of the Association by three (3) arbitrators appointed in accordance
71 // with the said Rules.
72 // The place of arbitration shall be in Taipei, Taiwan and the language shall
73 // be English.
74 // The arbitration award shall be final and binding to both parties.
75 //
76 //******************************************************************************
77 //<MStar Software>
78 ////////////////////////////////////////////////////////////////////////////////
79 //
80 // Copyright (c) 2006-2009 MStar Semiconductor, Inc.
81 // All rights reserved.
82 //
83 // Unless otherwise stipulated in writing, any and all information contained
84 // herein regardless in any format shall remain the sole proprietary of
85 // MStar Semiconductor Inc. and be kept in strict confidence
86 // (�uMStar Confidential Information�v) by the recipient.
87 // Any unauthorized act including without limitation unauthorized disclosure,
88 // copying, use, reproduction, sale, distribution, modification, disassembling,
89 // reverse engineering and compiling of the contents of MStar Confidential
90 // Information is unlawful and strictly prohibited. MStar hereby reserves the
91 // rights to any and all damages, losses, costs and expenses resulting therefrom.
92 //
93 ////////////////////////////////////////////////////////////////////////////////
94
95
96 #include <assert.h>
97 #include <string.h>
98
99 #include "MFE_chip.h"
100 #include "mfe_common.h"
101 #include "mfe_type.h"
102 #include "madp_ms_dprintf.h"
103
104 #include "MuxCommon.h"
105 #include "TsMuxer.h"
106 #include <pthread.h>
107 #ifdef FILE_TEST
108 #include <stdio.h>
109 #endif
110
111 #define MAX_VALUE (1<<30)
112 //#define INVALID_PTS ((INT64_C)(0x8000000000000000LL))
113
114 #define TS_SYNCBYTE 0x47
115 #define TS_PACKET_SIZE 188
116
117 #ifdef TS_192_BYTE
118 #define TIMECODE_AHEAD 1000
119 #define TIMECODE_CLOCK 90000//27000000
120 #endif
121
122 #define DEFAULT_SID 0x0001
123 #define DEFAULT_PMT_START_PID 0x0100
124 #define DEFAULT_START_PID 0x0064 // Valid range [0x0010, 0x1FFE]
125
126 // PAT
127 #define TID_PAT 0x00 // table_id
128 #define TSID_DEFAULT 0x0001 // transport_stream_id
129 #define PID_PAT 0x0000
130
131 // PMT stream_type
132 #define PMT_STREAM_TYPE_13818_2 0x02
133 #define PMT_STREAM_TYPE_11172_3 0x03
134 #define PMT_STREAM_TYPE_14496_2 0x10
135 #define PMT_STREAM_TYPE_14496_10 0x1b
136 #define TID_PMT 0x02 // table_id
137
138 // PES related
139 #define DEFAULT_PES_HEADER_FREQ 16
140 #define DEFAULT_PES_PAYLOAD_SIZE ((DEFAULT_PES_HEADER_FREQ - 1) * 184 + 170)
141 #define PES_NO_VIDEO_PAYLOADSIZE // If defined, PES payload size is filled as 0
142 #define PES_MAX_PAYLOADSIZE 0xFFFF
143
144 #define PAT_RETRANS_TIME 100
145
146 #define PCR_TRANSMISSION
147 #define PCR_RETRANS_TIME 20
148
149 //////////////////////////////////////////////////////////////////////////
150 // MPEG-TS SI info
151 //////////////////////////////////////////////////////////////////////////
152
153 static const MFE_U32 gCRC32Table[256] = {
154 0x00000000, 0xB71DC104, 0x6E3B8209, 0xD926430D, 0xDC760413, 0x6B6BC517, 0xB24D861A, 0x0550471E,
155 0xB8ED0826, 0x0FF0C922, 0xD6D68A2F, 0x61CB4B2B, 0x649B0C35, 0xD386CD31, 0x0AA08E3C, 0xBDBD4F38,
156 0x70DB114C, 0xC7C6D048, 0x1EE09345, 0xA9FD5241, 0xACAD155F, 0x1BB0D45B, 0xC2969756, 0x758B5652,
157 0xC836196A, 0x7F2BD86E, 0xA60D9B63, 0x11105A67, 0x14401D79, 0xA35DDC7D, 0x7A7B9F70, 0xCD665E74,
158 0xE0B62398, 0x57ABE29C, 0x8E8DA191, 0x39906095, 0x3CC0278B, 0x8BDDE68F, 0x52FBA582, 0xE5E66486,
159 0x585B2BBE, 0xEF46EABA, 0x3660A9B7, 0x817D68B3, 0x842D2FAD, 0x3330EEA9, 0xEA16ADA4, 0x5D0B6CA0,
160 0x906D32D4, 0x2770F3D0, 0xFE56B0DD, 0x494B71D9, 0x4C1B36C7, 0xFB06F7C3, 0x2220B4CE, 0x953D75CA,
161 0x28803AF2, 0x9F9DFBF6, 0x46BBB8FB, 0xF1A679FF, 0xF4F63EE1, 0x43EBFFE5, 0x9ACDBCE8, 0x2DD07DEC,
162 0x77708634, 0xC06D4730, 0x194B043D, 0xAE56C539, 0xAB068227, 0x1C1B4323, 0xC53D002E, 0x7220C12A,
163 0xCF9D8E12, 0x78804F16, 0xA1A60C1B, 0x16BBCD1F, 0x13EB8A01, 0xA4F64B05, 0x7DD00808, 0xCACDC90C,
164 0x07AB9778, 0xB0B6567C, 0x69901571, 0xDE8DD475, 0xDBDD936B, 0x6CC0526F, 0xB5E61162, 0x02FBD066,
165 0xBF469F5E, 0x085B5E5A, 0xD17D1D57, 0x6660DC53, 0x63309B4D, 0xD42D5A49, 0x0D0B1944, 0xBA16D840,
166 0x97C6A5AC, 0x20DB64A8, 0xF9FD27A5, 0x4EE0E6A1, 0x4BB0A1BF, 0xFCAD60BB, 0x258B23B6, 0x9296E2B2,
167 0x2F2BAD8A, 0x98366C8E, 0x41102F83, 0xF60DEE87, 0xF35DA999, 0x4440689D, 0x9D662B90, 0x2A7BEA94,
168 0xE71DB4E0, 0x500075E4, 0x892636E9, 0x3E3BF7ED, 0x3B6BB0F3, 0x8C7671F7, 0x555032FA, 0xE24DF3FE,
169 0x5FF0BCC6, 0xE8ED7DC2, 0x31CB3ECF, 0x86D6FFCB, 0x8386B8D5, 0x349B79D1, 0xEDBD3ADC, 0x5AA0FBD8,
170 0xEEE00C69, 0x59FDCD6D, 0x80DB8E60, 0x37C64F64, 0x3296087A, 0x858BC97E, 0x5CAD8A73, 0xEBB04B77,
171 0x560D044F, 0xE110C54B, 0x38368646, 0x8F2B4742, 0x8A7B005C, 0x3D66C158, 0xE4408255, 0x535D4351,
172 0x9E3B1D25, 0x2926DC21, 0xF0009F2C, 0x471D5E28, 0x424D1936, 0xF550D832, 0x2C769B3F, 0x9B6B5A3B,
173 0x26D61503, 0x91CBD407, 0x48ED970A, 0xFFF0560E, 0xFAA01110, 0x4DBDD014, 0x949B9319, 0x2386521D,
174 0x0E562FF1, 0xB94BEEF5, 0x606DADF8, 0xD7706CFC, 0xD2202BE2, 0x653DEAE6, 0xBC1BA9EB, 0x0B0668EF,
175 0xB6BB27D7, 0x01A6E6D3, 0xD880A5DE, 0x6F9D64DA, 0x6ACD23C4, 0xDDD0E2C0, 0x04F6A1CD, 0xB3EB60C9,
176 0x7E8D3EBD, 0xC990FFB9, 0x10B6BCB4, 0xA7AB7DB0, 0xA2FB3AAE, 0x15E6FBAA, 0xCCC0B8A7, 0x7BDD79A3,
177 0xC660369B, 0x717DF79F, 0xA85BB492, 0x1F467596, 0x1A163288, 0xAD0BF38C, 0x742DB081, 0xC3307185,
178 0x99908A5D, 0x2E8D4B59, 0xF7AB0854, 0x40B6C950, 0x45E68E4E, 0xF2FB4F4A, 0x2BDD0C47, 0x9CC0CD43,
179 0x217D827B, 0x9660437F, 0x4F460072, 0xF85BC176, 0xFD0B8668, 0x4A16476C, 0x93300461, 0x242DC565,
180 0xE94B9B11, 0x5E565A15, 0x87701918, 0x306DD81C, 0x353D9F02, 0x82205E06, 0x5B061D0B, 0xEC1BDC0F,
181 0x51A69337, 0xE6BB5233, 0x3F9D113E, 0x8880D03A, 0x8DD09724, 0x3ACD5620, 0xE3EB152D, 0x54F6D429,
182 0x7926A9C5, 0xCE3B68C1, 0x171D2BCC, 0xA000EAC8, 0xA550ADD6, 0x124D6CD2, 0xCB6B2FDF, 0x7C76EEDB,
183 0xC1CBA1E3, 0x76D660E7, 0xAFF023EA, 0x18EDE2EE, 0x1DBDA5F0, 0xAAA064F4, 0x738627F9, 0xC49BE6FD,
184 0x09FDB889, 0xBEE0798D, 0x67C63A80, 0xD0DBFB84, 0xD58BBC9A, 0x62967D9E, 0xBBB03E93, 0x0CADFF97,
185 0xB110B0AF, 0x060D71AB, 0xDF2B32A6, 0x6836F3A2, 0x6D66B4BC, 0xDA7B75B8, 0x035D36B5, 0xB440F7B1,
186 };
187
getCRC(const MFE_U8 * buffer,size_t length)188 MFE_U32 getCRC(const MFE_U8 *buffer, size_t length)
189 {
190 const MFE_U8 *end= buffer+length;
191 MFE_U32 crc = 0xFFFFFFFF;
192 while(buffer<end)
193 crc = (crc >> 8) ^ gCRC32Table[(crc & 0xFF) ^ *buffer++];
194 return crc;
195 }
196
197 #ifdef TS_192_BYTE
GetTimecode(MediaContext * ctx,int data_len)198 MFE_U32 GetTimecode(MediaContext* ctx, int data_len)
199 {
200 int mux_rate, increment;
201 MpegTSWrite *ts = (MpegTSWrite*)ctx->muxinfo;
202
203 if (ts->waited_datasize<=0 || ts->min_time<=ctx->timestamp+TIMECODE_AHEAD)
204 mux_rate = ts->mux_rate;
205 else
206 mux_rate = ts->waited_datasize * TIMECODE_CLOCK / (int)(ts->min_time - (ctx->timestamp+TIMECODE_AHEAD));
207 ts->waited_datasize -= data_len;
208
209 increment = data_len * TIMECODE_CLOCK / mux_rate - 1;
210 if (increment<=0) increment = 1;
211 ctx->timestamp += increment;
212 #if 0
213 assert(ctx->streams[0]->payload_pts==INVALID_PTS || ctx->timestamp<ctx->streams[0]->payload_pts);
214 assert(ctx->streams[1]->payload_pts==INVALID_PTS || ctx->timestamp<ctx->streams[1]->payload_pts);
215 #endif
216 return (MFE_U32)(ctx->timestamp & 0x3FFFFFFF); // % 2^30
217 }
218 #endif
219
mpegts_write_section(MediaContext * ctx,MpegTSSection * s,int table_id,int id,MFE_U8 * section,MFE_U32 len)220 static void mpegts_write_section(MediaContext* ctx, MpegTSSection *s, int table_id, int id, MFE_U8 *section, MFE_U32 len)
221 {
222 MFE_U8 *q, *buf_ptr;
223 MFE_U32 tot_len, first, b, len1, left, crc;
224 MpegTSWrite *ts = (MpegTSWrite*)ctx->muxinfo;
225 MFE_U8 packet[TS_PACKET_SIZE];
226 OutDataInfo data_info;
227
228 tot_len = 8 + len + 4; // 4: CRC bytes
229 assert(tot_len<=1024);
230
231 // First common 8 bytes
232 q = section;
233 *q++ = table_id;
234 put16_msbf(&q, 0xb000 | (len + 5 + 4)); // header:5 , CRC:4
235 put16_msbf(&q, id); // transport_stream_id (PAT) or program_number (PMT)
236 *q++ = 0xc1; // version_number=0, current_next_indicator=1
237 *q++ = 0x0; // section_number
238 *q++ = 0x0; // last_section_number
239
240 // CRC
241 crc = getCRC(section, tot_len - 4);
242 buf_ptr = §ion[tot_len-4];
243 put32_lsbf(&buf_ptr, crc);
244
245 // ts packets
246 buf_ptr = section;
247 while (tot_len > 0) {
248 first = (section == buf_ptr);
249 q = packet;
250 *q++ = TS_SYNCBYTE;
251 b = (s->pid >> 8);
252 if (first)
253 b |= 0x40; // payload_unit_start_indicator=1
254 *q++ = b;
255 *q++ = s->pid;
256 *q++ = 0x10 | s->cc; // no scrambling, payload only
257 s->cc = (s->cc + 1) & 0xF;
258 if (first)
259 *q++ = 0x00; // pointer_field
260 len1 = TS_PACKET_SIZE - (q - packet);
261 if (len1 > tot_len)
262 len1 = tot_len;
263 memcpy(q, buf_ptr, len1);
264 q += len1;
265 // padding bytes
266 left = TS_PACKET_SIZE - (q - packet);
267 if (left > 0)
268 memset(q, 0xFF, left);
269
270 data_info.header = packet;
271 data_info.size1 = TS_PACKET_SIZE;
272 data_info.data = 0;
273 data_info.size2 = 0;
274 data_info.write_type = 1;
275 data_info.type = INDEX_TYPE_NONE;
276 #ifdef TS_192_BYTE
277 data_info.write_timecode = 1;
278 data_info.timecode = GetTimecode(ctx, 0);
279 #else
280 data_info.write_timecode = 0;
281 #endif
282 data_info.stuffing = 0;
283 data_info.lock_write = 0;
284 data_info.update_count = 0;
285 outbuf_put(ctx->outstream, &data_info);
286
287 buf_ptr += len1;
288 tot_len -= len1;
289 #ifdef PCR_TRANSMISSION
290 ts->cur_pcr += TS_PACKET_SIZE*8*90000L/ts->mux_rate;
291 #endif
292 }
293 }
294
295 // Only 1 program
mpegts_write_pat(MediaContext * s)296 static void mpegts_write_pat(MediaContext *s)
297 {
298 MpegTSWrite *ts = (MpegTSWrite*)s->muxinfo;
299 MFE_U8 data[1024], *q, *pat_start;
300
301 q = pat_start = data+8;
302 put16_msbf(&q, ts->program.prog_num); // program_number
303 put16_msbf(&q, 0xe000 | ts->program.pmt.pid); // program_map_PID
304 mpegts_write_section(s, &ts->pat, TID_PAT, ts->tsid, data, q - pat_start);
305 }
306
mpegts_write_pmt(MediaContext * s,MpegTSProgram * program)307 static void mpegts_write_pmt(MediaContext *s, MpegTSProgram *program)
308 {
309 MFE_U8 data[1024], *q, *pmt_start, *p_es_desc_len, *p_prog_desc_len;
310 int val;
311 MFE_U32 stream_type=0, i;
312
313 q = pmt_start = data+8;
314 put16_msbf(&q, 0xE000 | program->pcr_pid);
315
316 p_prog_desc_len = q;
317 q += 2;
318
319 // Optional program descriptor goes here
320
321 val = 0xF000 | (q - p_prog_desc_len - 2);
322 p_prog_desc_len[0] = val >> 8;
323 p_prog_desc_len[1] = val;
324
325 for (i=0; i<s->stream_count; i++) {
326 StreamContext *st = s->streams[i];
327 switch(st->codec_id) {
328 case CODEC_ID_VIDEO_MPEG4:
329 stream_type = PMT_STREAM_TYPE_14496_2;
330 break;
331 case CODEC_ID_AUDIO_MP2:
332 case CODEC_ID_AUDIO_MP3:
333 stream_type = PMT_STREAM_TYPE_11172_3;
334 break;
335 case CODEC_ID_VIDEO_MPEG2:
336 stream_type = PMT_STREAM_TYPE_13818_2;
337 break;
338 case CODEC_ID_VIDEO_H264:
339 stream_type = PMT_STREAM_TYPE_14496_10;
340 break;
341 case CODEC_ID_NONE:
342 assert(0);
343 //printf("wrong codec in TSMUXER\n");
344 break;
345 }
346 *q++ = stream_type;
347 put16_msbf(&q, 0xE000 | st->pid);
348 p_es_desc_len = q;
349 q += 2;
350
351 // Optional stream descriptor goes here
352 switch(st->codec_type) {
353 case CODEC_TYPE_AUDIO:
354 break;
355 case CODEC_TYPE_VIDEO:
356 break;
357 }
358
359 val = 0xF000 | (q - p_es_desc_len - 2);
360 p_es_desc_len[0] = val >> 8;
361 p_es_desc_len[1] = val;
362 }
363 mpegts_write_section(s, &program->pmt, TID_PMT, program->prog_num, data, q - pmt_start);
364 }
365
resend_PAT_PMT(MediaContext * s)366 static void resend_PAT_PMT(MediaContext *s)
367 {
368 MpegTSWrite *ts = (MpegTSWrite*)s->muxinfo;
369
370 if (++ts->pat_packet_count == ts->pat_packet_freq) {
371 ts->pat_packet_count = 0;
372 mpegts_write_pat(s);
373 mpegts_write_pmt(s, &ts->program);
374 }
375 }
376
377 //////////////////////////////////////////////////////////////////////////
378 // MPEG-TS PES packet
379 //////////////////////////////////////////////////////////////////////////
380
381 // Write 33-bit PTS or DTS
write_ptsdts(MFE_U8 * q,int fourbits,MFE_S64 pts)382 static void write_ptsdts(MFE_U8 *q, int fourbits, MFE_S64 pts)
383 {
384 int val;
385
386 pts = pts & MFE_INT64_C(0x1FFFFFFFF); // % 2^33
387 // pts &= (MFE_S64)(0x1FFFFFFFF); // % 2^33
388
389 val = fourbits << 4 | ((((MFE_U32)(pts>>30)) & 0x07) << 1) | 1;
390 *q++ = val;
391 val = ((((MFE_U32)(pts>>15)) & 0x7fff) << 1) | 1;
392 *q++ = val >> 8;
393 *q++ = val;
394 val = (((MFE_U32)(pts&0x7fff)) << 1) | 1;
395 *q++ = val >> 8;
396 *q++ = val;
397 }
398
399 // The payload must be either:
400 // one video frame (with headers after the last bytes of the last frame), or
401 // one audio frame.
402 // If audio stream, index_type must be INDEX_TYPE_NONE.
mpegts_write_pes(MediaContext * s,StreamContext * st,MFE_U32 payload_size,INDEX_TYPE_T index_type,MFE_U8 first,MFE_U8 last)403 static void mpegts_write_pes(MediaContext *s, StreamContext *st, MFE_U32 payload_size, INDEX_TYPE_T index_type, MFE_U8 first, MFE_U8 last)
404 {
405 MpegTSWrite *ts = (MpegTSWrite*)s->muxinfo;
406 MpegTSProgram* program = (MpegTSProgram*)st->program;
407 MFE_U8 *payload = st->payload;
408 MFE_S64 pts = st->payload_pts;
409 MFE_S64 dts = st->payload_dts;
410 MFE_U8 buf[TS_PACKET_SIZE];
411 MFE_U8 *q;
412 int val, is_start, write_pcr, flags;
413 MFE_U32 len, header_len, data_len, stuffing_len;
414 INDEX_TYPE_T type;
415 OutDataInfo data_info;
416 #ifdef PCR_TRANSMISSION
417 MFE_S64 pcr;
418 #endif
419
420 //assert( !(index_type!=INDEX_TYPE_NONE&&!last) );
421
422 is_start = first;//1;
423 stuffing_len = 0;
424 if (ts->temp_size>0) {
425 assert(ts->temp_size<=TS_PACKET_SIZE);
426 payload -= ts->temp_size;
427 payload_size += ts->temp_size;
428 memcpy(payload, ts->temp188, ts->temp_size);
429 ts->temp_size = 0;
430 }
431 type = index_type;
432 while (payload_size > 0) {
433 resend_PAT_PMT(s);
434
435 write_pcr = 0;
436 #ifdef PCR_TRANSMISSION
437 if (st->pid == program->pcr_pid) {
438 program->pcr_packet_count++;
439 if (program->pcr_packet_count>=program->pcr_packet_freq) {
440 program->pcr_packet_count = 0;
441 write_pcr = 1;
442 }
443 }
444 #endif
445 // ts packet header: 4 bytes
446 q = buf;
447 *q++ = TS_SYNCBYTE;
448 val = (st->pid >> 8);
449 if (is_start)
450 val |= 0x40; // payload_unit_start_indicator=1
451 *q++ = (MFE_U8)val;
452 *q++ = (MFE_U8)st->pid;
453 *q++ = (MFE_U8)((write_pcr ? 0x30 : 0x10) | st->cc); // no scrambling
454 //st->cc = (st->cc + 1) & 0xF;
455
456 // adaptation_field and/or PES_packet() starts here.
457 #ifdef PCR_TRANSMISSION
458 if (write_pcr) {
459 // add 11, pcr references the last byte of program clock reference base
460 pcr = ts->cur_pcr + (4+7)*8*90000L / ts->mux_rate;
461 if (dts != INVALID_PTS && dts < pcr)
462 assert(0);
463 *q++ = 7; // adaptation_field_length
464 *q++ = 0x10; // Has PCR
465 *q++ = (MFE_U8)(pcr >> 25);
466 *q++ = (MFE_U8)(pcr >> 17);
467 *q++ = (MFE_U8)(pcr >> 9);
468 *q++ = (MFE_U8)(pcr >> 1);
469 *q++ = (MFE_U8)((pcr&1) << 7);
470 *q++ = 0;
471 }
472 #endif
473 // Stuffing bytes by adaptation_field, if necessary.
474 header_len = q-buf;
475 if (is_start) {
476 header_len += 9;
477 if (pts != INVALID_PTS) {
478 header_len += 5;
479 if (dts != pts)
480 header_len += 5;
481 }
482 }
483 data_len = TS_PACKET_SIZE - header_len;
484 if (data_len > payload_size) {
485 stuffing_len = data_len - payload_size;
486 data_len = payload_size;
487 if (buf[3] & 0x20) {
488 // already has adaptation_field
489 len = buf[4] + 1;
490 buf[4] += stuffing_len; // Update length
491 memset(q, 0xFF, stuffing_len);
492 q += stuffing_len;
493 }
494 else {
495 buf[3] |= 0x20; // notify existence of adaptation_field
496 *q++ = stuffing_len-1; // adaptation_field_length is used for 1-byte stuffing.
497 if (stuffing_len >= 2) {
498 *q++ = 0x00; // All flags are zero.
499 memset(q, 0xFF, stuffing_len-2);
500 q += stuffing_len-2;
501 }
502 }
503 }
504
505 if (is_start) {
506 // PES header
507 *q++ = 0x00;
508 *q++ = 0x00;
509 *q++ = 0x01;
510 if (st->codec_type == CODEC_TYPE_VIDEO) {
511 *q++ = 0xe0; // MPEG-1 or MPEG-2 or MPEG-4 or H.264 video
512 } else if (st->codec_type == CODEC_TYPE_AUDIO &&
513 (st->codec_id==CODEC_ID_AUDIO_MP2 || st->codec_id==CODEC_ID_AUDIO_MP3)) {
514 *q++ = 0xc0;
515 }
516 header_len = 0;
517 flags = 0;
518 if (pts != INVALID_PTS) {
519 header_len += 5;
520 flags |= 0x80;
521 if (dts != pts) {
522 header_len += 5;
523 flags |= 0x40;
524 }
525 }
526 len = payload_size + header_len + 3;
527 #ifdef PES_NO_VIDEO_PAYLOADSIZE
528 if (st->codec_type == CODEC_TYPE_VIDEO) {
529 *q++ = 0;
530 *q++ = 0;
531 }
532 else
533 #endif
534 {
535 assert(len<PES_MAX_PAYLOADSIZE);
536 *q++ = len >> 8;
537 *q++ = len;
538 }
539 val = 0x80;
540 *q++ = val;
541 *q++ = flags;
542 *q++ = header_len;
543 if (pts != INVALID_PTS) {
544 write_ptsdts(q, flags >> 6, pts);
545 q += 5;
546 if (dts != pts) {
547 write_ptsdts(q, 1, dts);
548 q += 5;
549 }
550 }
551 //is_start = 0;
552 }
553
554 // pes_packet_data_byte
555 //memcpy(q, payload, data_len);
556 assert(q+data_len-buf==TS_PACKET_SIZE);
557
558 if (!last && stuffing_len>0) {
559 assert(ts->temp_size==0);
560 memcpy(ts->temp188, payload, payload_size);
561 ts->temp_size = payload_size;
562 break;
563 }
564
565 data_info.header = buf;
566 data_info.size1 = TS_PACKET_SIZE-data_len;
567 data_info.data = payload;
568 data_info.size2 = data_len;
569 data_info.write_type = 1;
570 data_info.type = (last&&is_start) ? type : INDEX_TYPE_NONE;
571 #ifdef TS_192_BYTE
572 data_info.write_timecode = 1;
573 data_info.timecode = GetTimecode(s, data_len);
574 #else
575 data_info.write_timecode = 0;
576 #endif
577 data_info.stuffing = 0;
578 data_info.lock_write = last ? 0 : 1;
579 data_info.update_count = 0;
580 outbuf_put(s->outstream, &data_info);
581
582 // Prepare for next round
583 st->cc = (st->cc + 1) & 0xF;
584 payload += data_len;
585 payload_size -= data_len;
586 if (is_start) {
587 is_start = 0;
588 type = INDEX_TYPE_NONE;
589 }
590 #ifdef PCR_TRANSMISSION
591 ts->cur_pcr += TS_PACKET_SIZE*8*90000L/ts->mux_rate;
592 #endif
593 }
594 }
595
596 //////////////////////////////////////////////////////////////////////////
597 // TS-mux external API's
598 //////////////////////////////////////////////////////////////////////////
599
tsmux_open(struct avmux_s * inst)600 int tsmux_open(struct avmux_s *inst)
601 {
602 MediaContext *s = inst->mctx;
603 MpegTSWrite *ctx = (MpegTSWrite*)s->muxinfo;
604 MpegTSProgram *program = &ctx->program;
605 StreamContext *st;
606 MFE_U32 i, total_bit_rate;
607 MFE_U32 pat_pmt_size;
608 MFE_U64 pos;
609
610 #ifdef TS_192_BYTE
611 s->timestamp = 0;
612 #endif
613
614 outbuf_init(s->outstream);
615
616 ctx->tsid = TSID_DEFAULT;
617 ctx->pat.pid = PID_PAT;
618 ctx->pat.cc = 0;
619 ctx->pat_packet_count = 0;
620 ctx->cur_pcr = 0;
621 ctx->temp_size = 0;
622 ctx->min_time = 0;
623 ctx->waited_datasize = 0;
624
625 /* Initial the single program */
626 program->pmt.pid = DEFAULT_PMT_START_PID;
627 program->pmt.cc =0;
628 program->prog_num = DEFAULT_SID;
629 program->pcr_pid = 0x1FFF;
630 program->pcr_packet_count = 0;
631
632 // Initial streams
633 total_bit_rate = 0;
634 for(i=0; i<s->stream_count; i++) {
635 st = s->streams[i];
636 st->cc = 0;
637 st->program = program;
638 if (st->pid==0) // If not forced.
639 st->pid = DEFAULT_START_PID + i;
640 st->payload_pts = INVALID_PTS;
641 st->payload_dts = INVALID_PTS;
642 // PCR pid is the first video stream
643 if (st->codec_type == CODEC_TYPE_VIDEO && program->pcr_pid == 0x1FFF)
644 program->pcr_pid = st->pid;
645 total_bit_rate += st->bit_rate;
646 }
647
648 // if no video stream, use the first stream as PCR
649 if (program->pcr_pid == 0x1FFF && s->stream_count > 0) {
650 program->pcr_pid = s->streams[0]->pid;
651 }
652
653 if (total_bit_rate <= 8 * 1024)
654 total_bit_rate = 8 * 1024;
655 program->pcr_packet_freq = MAX_VALUE;//(total_bit_rate * PCR_RETRANS_TIME) / (TS_PACKET_SIZE * 8 * 1000);
656 ctx->pat_packet_freq = MAX_VALUE;//(total_bit_rate * PAT_RETRANS_TIME) / (TS_PACKET_SIZE * 8 * 1000);
657
658 ctx->mux_rate = 1+total_bit_rate;
659 pos = s->outstream->total_size;
660 mpegts_write_pat(s);
661 mpegts_write_pmt(s, &ctx->program);
662 pat_pmt_size = (MFE_U32)(s->outstream->total_size - pos);
663
664 total_bit_rate +=
665 total_bit_rate * 25 / (8 * DEFAULT_PES_PAYLOAD_SIZE) // PES header
666 + total_bit_rate * 4 / (8 * TS_PACKET_SIZE) // TS header
667 + PAT_RETRANS_TIME * pat_pmt_size // PAT+PMT size
668 #ifdef PCR_TRANSMISSION
669 + PCR_RETRANS_TIME * 8 // PCR size
670 #endif
671 ;
672 ctx->mux_rate = total_bit_rate;
673
674 #ifdef PCR_TRANSMISSION
675 ctx->cur_pcr /= ctx->mux_rate;
676 #endif
677
678 return 0;
679 }
680
tsmux_write_packet(struct avmux_s * inst,AUContext * pkt)681 int tsmux_write_packet(struct avmux_s *inst, AUContext *pkt)
682 {
683 MediaContext *s = inst->mctx;
684 #ifdef TS_192_BYTE
685 MpegTSWrite *ts = (MpegTSWrite*)s->muxinfo;
686 int i;
687 MFE_S64 min_ts;
688 #endif
689 StreamContext *st = s->streams[pkt->stream_index];
690 MFE_U8 *buf= pkt->access_unit;
691 //const MFE_U8 *access_unit_index = NULL;
692 MFE_S64 dts = INVALID_PTS, pts = INVALID_PTS;
693
694 //assert(pkt->first_segment==1 && pkt->last_segment==1);
695 if (pkt->pts != INVALID_PTS)
696 pts = pkt->pts;
697 if (pkt->dts != INVALID_PTS)
698 dts = pkt->dts;
699
700 st->payload = buf;
701 st->payload_dts = dts;
702 st->payload_pts = pts;
703
704 #ifdef TS_192_BYTE
705 if (pkt->first_segment) {
706 assert(pts!=INVALID_PTS);
707 min_ts = s->streams[0]->payload_pts==INVALID_PTS ? 0 : s->streams[0]->payload_pts;
708 for (i=1; i<(int)s->stream_count; i++) {
709 if (s->streams[i]->payload_pts==INVALID_PTS)
710 min_ts = 0;
711 else if (s->streams[i]->payload_pts<min_ts)
712 min_ts = s->streams[i]->payload_pts;
713 }
714 ts->min_time = min_ts;
715 }
716 ts->waited_datasize += pkt->unit_size;
717 #endif
718
719 mpegts_write_pes(s, st, pkt->unit_size, pkt->index_type, pkt->first_segment, pkt->last_segment);
720 return 0;
721 }
722
tsmux_close(struct avmux_s * inst)723 int tsmux_close(struct avmux_s *inst)
724 {
725 MediaContext *s = inst->mctx;
726 outbuf_flush(s->outstream);
727 outbuf_close(s->outstream);
728 return 0;
729 }
730