changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext...
[libav.git] / libavformat / mpegtsenc.c
CommitLineData
5dbafeb7
FB
1/*
2 * MPEG2 transport stream (aka DVB) mux
3 * Copyright (c) 2003 Fabrice Bellard.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19#include "avformat.h"
20
21#include "mpegts.h"
22
23/* write DVB SI sections */
24
49057904 25static const uint32_t crc_table[256] = {
5dbafeb7
FB
26 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
27 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
28 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
29 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
30 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
31 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
32 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
33 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
34 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
35 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
36 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
37 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
38 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
39 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
40 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
41 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
42 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
43 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
44 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
45 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
46 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
47 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
48 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
49 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
50 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
51 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
52 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
53 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
54 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
55 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
56 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
57 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
58 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
59 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
60 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
61 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
62 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
63 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
64 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
65 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
66 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
67 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
68 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
69};
70
71unsigned int mpegts_crc32(const uint8_t *data, int len)
72{
73 register int i;
74 unsigned int crc = 0xffffffff;
75
76 for (i=0; i<len; i++)
77 crc = (crc << 8) ^ crc_table[((crc >> 24) ^ *data++) & 0xff];
78
79 return crc;
80}
81
82/*********************************************/
83/* mpegts section writer */
84
85typedef struct MpegTSSection {
86 int pid;
87 int cc;
88 void (*write_packet)(struct MpegTSSection *s, const uint8_t *packet);
89 void *opaque;
90} MpegTSSection;
91
92/* NOTE: 4 bytes must be left at the end for the crc32 */
93void mpegts_write_section(MpegTSSection *s, uint8_t *buf, int len)
94{
95 unsigned int crc;
96 unsigned char packet[TS_PACKET_SIZE];
97 const unsigned char *buf_ptr;
98 unsigned char *q;
99 int first, b, len1, left;
100
101 crc = mpegts_crc32(buf, len - 4);
102 buf[len - 4] = (crc >> 24) & 0xff;
103 buf[len - 3] = (crc >> 16) & 0xff;
104 buf[len - 2] = (crc >> 8) & 0xff;
105 buf[len - 1] = (crc) & 0xff;
106
107 /* send each packet */
108 buf_ptr = buf;
109 while (len > 0) {
110 first = (buf == buf_ptr);
111 q = packet;
112 *q++ = 0x47;
113 b = (s->pid >> 8);
114 if (first)
115 b |= 0x40;
116 *q++ = b;
117 *q++ = s->pid;
118 s->cc = (s->cc + 1) & 0xf;
119 *q++ = 0x10 | s->cc;
120 if (first)
121 *q++ = 0; /* 0 offset */
122 len1 = TS_PACKET_SIZE - (q - packet);
123 if (len1 > len)
124 len1 = len;
125 memcpy(q, buf_ptr, len1);
126 q += len1;
127 /* add known padding data */
128 left = TS_PACKET_SIZE - (q - packet);
129 if (left > 0)
130 memset(q, 0xff, left);
131
132 s->write_packet(s, packet);
133
134 buf_ptr += len1;
135 len -= len1;
136 }
137}
138
139static inline void put16(uint8_t **q_ptr, int val)
140{
141 uint8_t *q;
142 q = *q_ptr;
143 *q++ = val >> 8;
144 *q++ = val;
145 *q_ptr = q;
146}
147
148int mpegts_write_section1(MpegTSSection *s, int tid, int id,
149 int version, int sec_num, int last_sec_num,
150 uint8_t *buf, int len)
151{
152 uint8_t section[1024], *q;
153 unsigned int tot_len;
154
155 tot_len = 3 + 5 + len + 4;
156 /* check if not too big */
157 if (tot_len > 1024)
158 return -1;
159
160 q = section;
161 *q++ = tid;
162 put16(&q, 0xb000 | (len + 5 + 4)); /* 5 byte header + 4 byte CRC */
163 put16(&q, id);
164 *q++ = 0xc1 | (version << 1); /* current_next_indicator = 1 */
165 *q++ = sec_num;
166 *q++ = last_sec_num;
167 memcpy(q, buf, len);
168
169 mpegts_write_section(s, section, tot_len);
170 return 0;
171}
172
173/*********************************************/
174/* mpegts writer */
175
176#define DEFAULT_PMT_START_PID 0x1000
177#define DEFAULT_START_PID 0x0100
178#define DEFAULT_PROVIDER_NAME "FFmpeg"
179#define DEFAULT_SERVICE_NAME "Service01"
180
181/* default network id, transport stream and service identifiers */
182#define DEFAULT_ONID 0x0001
183#define DEFAULT_TSID 0x0001
184#define DEFAULT_SID 0x0001
185
186/* a PES packet header is generated every DEFAULT_PES_HEADER_FREQ packets */
187#define DEFAULT_PES_HEADER_FREQ 16
69ef9450 188#define DEFAULT_PES_PAYLOAD_SIZE ((DEFAULT_PES_HEADER_FREQ - 1) * 184 + 170)
5dbafeb7
FB
189
190/* we retransmit the SI info at this rate */
191#define SDT_RETRANS_TIME 500
192#define PAT_RETRANS_TIME 100
8b475508 193#define PCR_RETRANS_TIME 20
5dbafeb7
FB
194
195typedef struct MpegTSWriteStream {
8b475508 196 struct MpegTSService *service;
5dbafeb7
FB
197 int pid; /* stream associated pid */
198 int cc;
69ef9450
FB
199 int payload_index;
200 int64_t payload_pts;
201 uint8_t payload[DEFAULT_PES_PAYLOAD_SIZE];
5dbafeb7
FB
202} MpegTSWriteStream;
203
204typedef struct MpegTSService {
205 MpegTSSection pmt; /* MPEG2 pmt table context */
5dbafeb7
FB
206 int sid; /* service ID */
207 char *name;
208 char *provider_name;
8b475508
FB
209 int pcr_pid;
210 int pcr_packet_count;
211 int pcr_packet_freq;
5dbafeb7
FB
212} MpegTSService;
213
214typedef struct MpegTSWrite {
215 MpegTSSection pat; /* MPEG2 pat table */
216 MpegTSSection sdt; /* MPEG2 sdt table context */
217 MpegTSService **services;
218 int sdt_packet_count;
219 int sdt_packet_freq;
220 int pat_packet_count;
221 int pat_packet_freq;
222 int nb_services;
223 int onid;
224 int tsid;
225} MpegTSWrite;
226
227static void mpegts_write_pat(AVFormatContext *s)
228{
229 MpegTSWrite *ts = s->priv_data;
230 MpegTSService *service;
231 uint8_t data[1012], *q;
232 int i;
233
234 q = data;
235 for(i = 0; i < ts->nb_services; i++) {
236 service = ts->services[i];
237 put16(&q, service->sid);
238 put16(&q, 0xe000 | service->pmt.pid);
239 }
240 mpegts_write_section1(&ts->pat, PAT_TID, ts->tsid, 0, 0, 0,
241 data, q - data);
242}
243
244static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
245{
246 // MpegTSWrite *ts = s->priv_data;
247 uint8_t data[1012], *q, *desc_length_ptr, *program_info_length_ptr;
248 int val, stream_type, i;
249
250 q = data;
251 put16(&q, 0xe000 | service->pcr_pid);
252
253 program_info_length_ptr = q;
254 q += 2; /* patched after */
255
256 /* put program info here */
257
258 val = 0xf000 | (q - program_info_length_ptr - 2);
259 program_info_length_ptr[0] = val >> 8;
260 program_info_length_ptr[1] = val;
261
262 for(i = 0; i < s->nb_streams; i++) {
263 AVStream *st = s->streams[i];
264 MpegTSWriteStream *ts_st = st->priv_data;
01f4895c 265 switch(st->codec->codec_id) {
278de475
MR
266 case CODEC_ID_MPEG1VIDEO:
267 case CODEC_ID_MPEG2VIDEO:
268 stream_type = STREAM_TYPE_VIDEO_MPEG2;
5dbafeb7 269 break;
278de475
MR
270 case CODEC_ID_MPEG4:
271 stream_type = STREAM_TYPE_VIDEO_MPEG4;
272 break;
273 case CODEC_ID_H264:
274 stream_type = STREAM_TYPE_VIDEO_H264;
275 break;
276 case CODEC_ID_MP2:
277 case CODEC_ID_MP3:
ce34182d 278 stream_type = STREAM_TYPE_AUDIO_MPEG1;
5dbafeb7 279 break;
278de475
MR
280 case CODEC_ID_AAC:
281 stream_type = STREAM_TYPE_AUDIO_AAC;
282 break;
283 case CODEC_ID_AC3:
284 stream_type = STREAM_TYPE_AUDIO_AC3;
285 break;
5dbafeb7
FB
286 default:
287 stream_type = STREAM_TYPE_PRIVATE_DATA;
288 break;
289 }
290 *q++ = stream_type;
291 put16(&q, 0xe000 | ts_st->pid);
292 desc_length_ptr = q;
293 q += 2; /* patched after */
294
295 /* write optional descriptors here */
01f4895c 296 switch(st->codec->codec_type) {
8b475508
FB
297 case CODEC_TYPE_AUDIO:
298 if (strlen(st->language) == 3) {
299 *q++ = 0x0a; /* ISO 639 language descriptor */
300 *q++ = 4;
301 *q++ = st->language[0];
302 *q++ = st->language[1];
303 *q++ = st->language[2];
304 *q++ = 0; /* undefined type */
305 }
306 break;
307 case CODEC_TYPE_SUBTITLE:
308 {
309 const char *language;
310 language = st->language;
311 if (strlen(language) != 3)
312 language = "eng";
313 *q++ = 0x59;
314 *q++ = 8;
315 *q++ = language[0];
316 *q++ = language[1];
317 *q++ = language[2];
318 *q++ = 0x10; /* normal subtitles (0x20 = if hearing pb) */
319 put16(&q, 1); /* page id */
320 put16(&q, 1); /* ancillary page id */
321 }
322 break;
323 }
5dbafeb7
FB
324
325 val = 0xf000 | (q - desc_length_ptr - 2);
326 desc_length_ptr[0] = val >> 8;
327 desc_length_ptr[1] = val;
328 }
329 mpegts_write_section1(&service->pmt, PMT_TID, service->sid, 0, 0, 0,
330 data, q - data);
331}
332
333/* NOTE: str == NULL is accepted for an empty string */
334static void putstr8(uint8_t **q_ptr, const char *str)
335{
336 uint8_t *q;
337 int len;
338
339 q = *q_ptr;
340 if (!str)
341 len = 0;
342 else
343 len = strlen(str);
344 *q++ = len;
345 memcpy(q, str, len);
346 q += len;
347 *q_ptr = q;
348}
349
350static void mpegts_write_sdt(AVFormatContext *s)
351{
352 MpegTSWrite *ts = s->priv_data;
353 MpegTSService *service;
354 uint8_t data[1012], *q, *desc_list_len_ptr, *desc_len_ptr;
355 int i, running_status, free_ca_mode, val;
356
357 q = data;
358 put16(&q, ts->onid);
359 *q++ = 0xff;
360 for(i = 0; i < ts->nb_services; i++) {
361 service = ts->services[i];
362 put16(&q, service->sid);
363 *q++ = 0xfc | 0x00; /* currently no EIT info */
364 desc_list_len_ptr = q;
365 q += 2;
366 running_status = 4; /* running */
367 free_ca_mode = 0;
368
369 /* write only one descriptor for the service name and provider */
370 *q++ = 0x48;
371 desc_len_ptr = q;
372 q++;
373 *q++ = 0x01; /* digital television service */
374 putstr8(&q, service->provider_name);
375 putstr8(&q, service->name);
376 desc_len_ptr[0] = q - desc_len_ptr - 1;
377
378 /* fill descriptor length */
379 val = (running_status << 13) | (free_ca_mode << 12) |
380 (q - desc_list_len_ptr - 2);
381 desc_list_len_ptr[0] = val >> 8;
382 desc_list_len_ptr[1] = val;
383 }
384 mpegts_write_section1(&ts->sdt, SDT_TID, ts->tsid, 0, 0, 0,
385 data, q - data);
386}
387
388static MpegTSService *mpegts_add_service(MpegTSWrite *ts,
389 int sid,
390 const char *provider_name,
391 const char *name)
392{
393 MpegTSService *service;
394
395 service = av_mallocz(sizeof(MpegTSService));
396 if (!service)
397 return NULL;
398 service->pmt.pid = DEFAULT_PMT_START_PID + ts->nb_services - 1;
399 service->sid = sid;
400 service->provider_name = av_strdup(provider_name);
401 service->name = av_strdup(name);
402 service->pcr_pid = 0x1fff;
403 dynarray_add(&ts->services, &ts->nb_services, service);
404 return service;
405}
406
407static void section_write_packet(MpegTSSection *s, const uint8_t *packet)
408{
409 AVFormatContext *ctx = s->opaque;
410 put_buffer(&ctx->pb, packet, TS_PACKET_SIZE);
411}
412
413static int mpegts_write_header(AVFormatContext *s)
414{
415 MpegTSWrite *ts = s->priv_data;
416 MpegTSWriteStream *ts_st;
417 MpegTSService *service;
418 AVStream *st;
419 int i, total_bit_rate;
8b475508
FB
420 const char *service_name;
421
5dbafeb7
FB
422 ts->tsid = DEFAULT_TSID;
423 ts->onid = DEFAULT_ONID;
424 /* allocate a single DVB service */
8b475508
FB
425 service_name = s->title;
426 if (service_name[0] == '\0')
427 service_name = DEFAULT_SERVICE_NAME;
5dbafeb7 428 service = mpegts_add_service(ts, DEFAULT_SID,
8b475508 429 DEFAULT_PROVIDER_NAME, service_name);
5dbafeb7
FB
430 service->pmt.write_packet = section_write_packet;
431 service->pmt.opaque = s;
432
433 ts->pat.pid = PAT_PID;
434 ts->pat.cc = 0;
435 ts->pat.write_packet = section_write_packet;
436 ts->pat.opaque = s;
437
438 ts->sdt.pid = SDT_PID;
439 ts->sdt.cc = 0;
440 ts->sdt.write_packet = section_write_packet;
441 ts->sdt.opaque = s;
442
443 /* assign pids to each stream */
444 total_bit_rate = 0;
445 for(i = 0;i < s->nb_streams; i++) {
446 st = s->streams[i];
447 ts_st = av_mallocz(sizeof(MpegTSWriteStream));
448 if (!ts_st)
449 goto fail;
450 st->priv_data = ts_st;
8b475508 451 ts_st->service = service;
5dbafeb7 452 ts_st->pid = DEFAULT_START_PID + i;
69ef9450 453 ts_st->payload_pts = AV_NOPTS_VALUE;
8b475508 454 /* update PCR pid by using the first video stream */
01f4895c 455 if (st->codec->codec_type == CODEC_TYPE_VIDEO &&
5dbafeb7
FB
456 service->pcr_pid == 0x1fff)
457 service->pcr_pid = ts_st->pid;
01f4895c 458 total_bit_rate += st->codec->bit_rate;
5dbafeb7 459 }
8b475508
FB
460
461 /* if no video stream, use the first stream as PCR */
462 if (service->pcr_pid == 0x1fff && s->nb_streams > 0) {
463 ts_st = s->streams[0]->priv_data;
464 service->pcr_pid = ts_st->pid;
465 }
466
5dbafeb7
FB
467 if (total_bit_rate <= 8 * 1024)
468 total_bit_rate = 8 * 1024;
8b475508
FB
469 service->pcr_packet_freq = (total_bit_rate * PCR_RETRANS_TIME) /
470 (TS_PACKET_SIZE * 8 * 1000);
5dbafeb7
FB
471 ts->sdt_packet_freq = (total_bit_rate * SDT_RETRANS_TIME) /
472 (TS_PACKET_SIZE * 8 * 1000);
473 ts->pat_packet_freq = (total_bit_rate * PAT_RETRANS_TIME) /
474 (TS_PACKET_SIZE * 8 * 1000);
475#if 0
476 printf("%d %d %d\n",
477 total_bit_rate, ts->sdt_packet_freq, ts->pat_packet_freq);
478#endif
479
480 /* write info at the start of the file, so that it will be fast to
481 find them */
482 mpegts_write_sdt(s);
483 mpegts_write_pat(s);
484 for(i = 0; i < ts->nb_services; i++) {
485 mpegts_write_pmt(s, ts->services[i]);
486 }
487 put_flush_packet(&s->pb);
488
489 return 0;
490
491 fail:
492 for(i = 0;i < s->nb_streams; i++) {
493 st = s->streams[i];
494 av_free(st->priv_data);
495 }
496 return -1;
497}
498
499/* send SDT, PAT and PMT tables regulary */
500static void retransmit_si_info(AVFormatContext *s)
501{
502 MpegTSWrite *ts = s->priv_data;
503 int i;
504
505 if (++ts->sdt_packet_count == ts->sdt_packet_freq) {
506 ts->sdt_packet_count = 0;
507 mpegts_write_sdt(s);
508 }
509 if (++ts->pat_packet_count == ts->pat_packet_freq) {
510 ts->pat_packet_count = 0;
511 mpegts_write_pat(s);
512 for(i = 0; i < ts->nb_services; i++) {
513 mpegts_write_pmt(s, ts->services[i]);
514 }
515 }
516}
517
69ef9450
FB
518/* NOTE: pes_data contains all the PES packet */
519static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
520 const uint8_t *payload, int payload_size,
521 int64_t pts)
5dbafeb7 522{
5dbafeb7 523 MpegTSWriteStream *ts_st = st->priv_data;
69ef9450 524 uint8_t buf[TS_PACKET_SIZE];
5dbafeb7 525 uint8_t *q;
8b475508
FB
526 int val, is_start, len, header_len, write_pcr, private_code;
527 int afc_len, stuffing_len;
528 int64_t pcr = -1; /* avoid warning */
5dbafeb7 529
69ef9450
FB
530 is_start = 1;
531 while (payload_size > 0) {
532 retransmit_si_info(s);
5dbafeb7 533
8b475508
FB
534 write_pcr = 0;
535 if (ts_st->pid == ts_st->service->pcr_pid) {
536 ts_st->service->pcr_packet_count++;
537 if (ts_st->service->pcr_packet_count >=
538 ts_st->service->pcr_packet_freq) {
539 ts_st->service->pcr_packet_count = 0;
540 write_pcr = 1;
541 /* XXX: this is incorrect, but at least we have a PCR
542 value */
543 pcr = pts;
544 }
545 }
546
69ef9450
FB
547 /* prepare packet header */
548 q = buf;
549 *q++ = 0x47;
550 val = (ts_st->pid >> 8);
551 if (is_start)
552 val |= 0x40;
553 *q++ = val;
554 *q++ = ts_st->pid;
8b475508 555 *q++ = 0x10 | ts_st->cc | (write_pcr ? 0x20 : 0);
69ef9450 556 ts_st->cc = (ts_st->cc + 1) & 0xf;
8b475508
FB
557 if (write_pcr) {
558 *q++ = 7; /* AFC length */
559 *q++ = 0x10; /* flags: PCR present */
560 *q++ = pcr >> 25;
561 *q++ = pcr >> 17;
562 *q++ = pcr >> 9;
563 *q++ = pcr >> 1;
564 *q++ = (pcr & 1) << 7;
565 *q++ = 0;
566 }
69ef9450
FB
567 if (is_start) {
568 /* write PES header */
569 *q++ = 0x00;
570 *q++ = 0x00;
571 *q++ = 0x01;
8b475508 572 private_code = 0;
01f4895c 573 if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
69ef9450 574 *q++ = 0xe0;
01f4895c
MN
575 } else if (st->codec->codec_type == CODEC_TYPE_AUDIO &&
576 (st->codec->codec_id == CODEC_ID_MP2 ||
577 st->codec->codec_id == CODEC_ID_MP3)) {
8b475508
FB
578 *q++ = 0xc0;
579 } else {
580 *q++ = 0xbd;
01f4895c 581 if (st->codec->codec_type == CODEC_TYPE_SUBTITLE) {
8b475508
FB
582 private_code = 0x20;
583 }
584 }
69ef9450
FB
585 if (pts != AV_NOPTS_VALUE)
586 header_len = 8;
587 else
588 header_len = 3;
8b475508
FB
589 if (private_code != 0)
590 header_len++;
69ef9450
FB
591 len = payload_size + header_len;
592 *q++ = len >> 8;
593 *q++ = len;
8b475508
FB
594 val = 0x80;
595 /* data alignment indicator is required for subtitle data */
01f4895c 596 if (st->codec->codec_type == CODEC_TYPE_SUBTITLE)
8b475508
FB
597 val |= 0x04;
598 *q++ = val;
69ef9450
FB
599 if (pts != AV_NOPTS_VALUE) {
600 *q++ = 0x80; /* PTS only */
601 *q++ = 0x05; /* header len */
602 val = (0x02 << 4) |
603 (((pts >> 30) & 0x07) << 1) | 1;
604 *q++ = val;
605 val = (((pts >> 15) & 0x7fff) << 1) | 1;
606 *q++ = val >> 8;
607 *q++ = val;
608 val = (((pts) & 0x7fff) << 1) | 1;
609 *q++ = val >> 8;
610 *q++ = val;
611 } else {
5dbafeb7
FB
612 *q++ = 0x00;
613 *q++ = 0x00;
5dbafeb7 614 }
8b475508
FB
615 if (private_code != 0)
616 *q++ = private_code;
69ef9450 617 is_start = 0;
5dbafeb7 618 }
8b475508
FB
619 /* header size */
620 header_len = q - buf;
621 /* data len */
622 len = TS_PACKET_SIZE - header_len;
69ef9450
FB
623 if (len > payload_size)
624 len = payload_size;
8b475508
FB
625 stuffing_len = TS_PACKET_SIZE - header_len - len;
626 if (stuffing_len > 0) {
627 /* add stuffing with AFC */
628 if (buf[3] & 0x20) {
629 /* stuffing already present: increase its size */
630 afc_len = buf[4] + 1;
631 memmove(buf + 4 + afc_len + stuffing_len,
632 buf + 4 + afc_len,
633 header_len - (4 + afc_len));
634 buf[4] += stuffing_len;
635 memset(buf + 4 + afc_len, 0xff, stuffing_len);
636 } else {
637 /* add stuffing */
638 memmove(buf + 4 + stuffing_len, buf + 4, header_len - 4);
639 buf[3] |= 0x20;
640 buf[4] = stuffing_len - 1;
641 if (stuffing_len >= 2) {
642 buf[5] = 0x00;
643 memset(buf + 6, 0xff, stuffing_len - 2);
644 }
645 }
646 }
647 memcpy(buf + TS_PACKET_SIZE - len, payload, len);
69ef9450
FB
648 payload += len;
649 payload_size -= len;
8b475508 650 put_buffer(&s->pb, buf, TS_PACKET_SIZE);
5dbafeb7
FB
651 }
652 put_flush_packet(&s->pb);
69ef9450
FB
653}
654
e928649b 655static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt)
69ef9450 656{
e928649b
MN
657 AVStream *st = s->streams[pkt->stream_index];
658 int size= pkt->size;
659 uint8_t *buf= pkt->data;
69ef9450 660 MpegTSWriteStream *ts_st = st->priv_data;
8b475508 661 int len, max_payload_size;
69ef9450 662
01f4895c 663 if (st->codec->codec_type == CODEC_TYPE_SUBTITLE) {
8b475508
FB
664 /* for subtitle, a single PES packet must be generated */
665 mpegts_write_pes(s, st, buf, size, pkt->pts);
666 return 0;
667 }
668
669 max_payload_size = DEFAULT_PES_PAYLOAD_SIZE;
69ef9450 670 while (size > 0) {
8b475508 671 len = max_payload_size - ts_st->payload_index;
69ef9450
FB
672 if (len > size)
673 len = size;
674 memcpy(ts_st->payload + ts_st->payload_index, buf, len);
675 buf += len;
676 size -= len;
677 ts_st->payload_index += len;
678 if (ts_st->payload_pts == AV_NOPTS_VALUE)
e928649b 679 ts_st->payload_pts = pkt->pts;
8b475508 680 if (ts_st->payload_index >= max_payload_size) {
69ef9450
FB
681 mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_index,
682 ts_st->payload_pts);
683 ts_st->payload_pts = AV_NOPTS_VALUE;
684 ts_st->payload_index = 0;
685 }
686 }
5dbafeb7
FB
687 return 0;
688}
689
690static int mpegts_write_end(AVFormatContext *s)
691{
692 MpegTSWrite *ts = s->priv_data;
693 MpegTSWriteStream *ts_st;
694 MpegTSService *service;
695 AVStream *st;
696 int i;
697
698 /* flush current packets */
699 for(i = 0; i < s->nb_streams; i++) {
700 st = s->streams[i];
701 ts_st = st->priv_data;
69ef9450
FB
702 if (ts_st->payload_index > 0) {
703 mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_index,
704 ts_st->payload_pts);
5dbafeb7
FB
705 }
706 }
707 put_flush_packet(&s->pb);
708
709 for(i = 0; i < ts->nb_services; i++) {
710 service = ts->services[i];
711 av_freep(&service->provider_name);
712 av_freep(&service->name);
713 av_free(service);
714 }
715 av_free(ts->services);
716
5dbafeb7
FB
717 return 0;
718}
719
720AVOutputFormat mpegts_mux = {
721 "mpegts",
722 "MPEG2 transport stream format",
723 "video/x-mpegts",
724 "ts",
725 sizeof(MpegTSWrite),
726 CODEC_ID_MP2,
69ef9450 727 CODEC_ID_MPEG2VIDEO,
5dbafeb7
FB
728 mpegts_write_header,
729 mpegts_write_packet,
730 mpegts_write_end,
731};