Statistics
| Branch: | Revision:

ffmpeg / libavformat / mpegtsenc.c @ 5509bffa

History | View | Annotate | Download (23.5 KB)

1 5dbafeb7 Fabrice Bellard
/*
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 5509bffa Diego Biurrun
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 5dbafeb7 Fabrice Bellard
 */
19
#include "avformat.h"
20
21
#include "mpegts.h"
22
23
/* write DVB SI sections */
24
25 49057904 Fabrice Bellard
static const uint32_t crc_table[256] = {
26 bb270c08 Diego Biurrun
        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 5dbafeb7 Fabrice Bellard
};
70
71
unsigned int mpegts_crc32(const uint8_t *data, int len)
72
{
73
    register int i;
74
    unsigned int crc = 0xffffffff;
75 115329f1 Diego Biurrun
76 5dbafeb7 Fabrice Bellard
    for (i=0; i<len; i++)
77
        crc = (crc << 8) ^ crc_table[((crc >> 24) ^ *data++) & 0xff];
78 115329f1 Diego Biurrun
79 5dbafeb7 Fabrice Bellard
    return crc;
80
}
81
82
/*********************************************/
83
/* mpegts section writer */
84
85
typedef 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 */
93
void 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 115329f1 Diego Biurrun
107 5dbafeb7 Fabrice Bellard
    /* 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 115329f1 Diego Biurrun
        if (len1 > len)
124 5dbafeb7 Fabrice Bellard
            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
139
static 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
148 115329f1 Diego Biurrun
int mpegts_write_section1(MpegTSSection *s, int tid, int id,
149 5dbafeb7 Fabrice Bellard
                          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 115329f1 Diego Biurrun
155 5dbafeb7 Fabrice Bellard
    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 115329f1 Diego Biurrun
169 5dbafeb7 Fabrice Bellard
    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
188 69ef9450 Fabrice Bellard
#define DEFAULT_PES_PAYLOAD_SIZE ((DEFAULT_PES_HEADER_FREQ - 1) * 184 + 170)
189 5dbafeb7 Fabrice Bellard
190
/* we retransmit the SI info at this rate */
191
#define SDT_RETRANS_TIME 500
192
#define PAT_RETRANS_TIME 100
193 8b475508 Fabrice Bellard
#define PCR_RETRANS_TIME 20
194 5dbafeb7 Fabrice Bellard
195
typedef struct MpegTSWriteStream {
196 8b475508 Fabrice Bellard
    struct MpegTSService *service;
197 5dbafeb7 Fabrice Bellard
    int pid; /* stream associated pid */
198
    int cc;
199 69ef9450 Fabrice Bellard
    int payload_index;
200
    int64_t payload_pts;
201
    uint8_t payload[DEFAULT_PES_PAYLOAD_SIZE];
202 5dbafeb7 Fabrice Bellard
} MpegTSWriteStream;
203
204
typedef struct MpegTSService {
205
    MpegTSSection pmt; /* MPEG2 pmt table context */
206
    int sid;           /* service ID */
207
    char *name;
208
    char *provider_name;
209 8b475508 Fabrice Bellard
    int pcr_pid;
210
    int pcr_packet_count;
211
    int pcr_packet_freq;
212 5dbafeb7 Fabrice Bellard
} MpegTSService;
213
214
typedef 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
227
static 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 115329f1 Diego Biurrun
234 5dbafeb7 Fabrice Bellard
    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
244
static 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 115329f1 Diego Biurrun
262 5dbafeb7 Fabrice Bellard
    for(i = 0; i < s->nb_streams; i++) {
263
        AVStream *st = s->streams[i];
264
        MpegTSWriteStream *ts_st = st->priv_data;
265 01f4895c Michael Niedermayer
        switch(st->codec->codec_id) {
266 278de475 Måns Rullgård
        case CODEC_ID_MPEG1VIDEO:
267
        case CODEC_ID_MPEG2VIDEO:
268
            stream_type = STREAM_TYPE_VIDEO_MPEG2;
269 5dbafeb7 Fabrice Bellard
            break;
270 278de475 Måns Rullgård
        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:
278 ce34182d Michael Niedermayer
            stream_type = STREAM_TYPE_AUDIO_MPEG1;
279 5dbafeb7 Fabrice Bellard
            break;
280 278de475 Måns Rullgård
        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;
286 5dbafeb7 Fabrice Bellard
        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 */
296 01f4895c Michael Niedermayer
        switch(st->codec->codec_type) {
297 8b475508 Fabrice Bellard
        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
        }
324 5dbafeb7 Fabrice Bellard
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 115329f1 Diego Biurrun
}
332 5dbafeb7 Fabrice Bellard
333
/* NOTE: str == NULL is accepted for an empty string */
334
static 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
350
static 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 115329f1 Diego Biurrun
357 5dbafeb7 Fabrice Bellard
    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 115329f1 Diego Biurrun
        val = (running_status << 13) | (free_ca_mode << 12) |
380 5dbafeb7 Fabrice Bellard
            (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
388 115329f1 Diego Biurrun
static MpegTSService *mpegts_add_service(MpegTSWrite *ts,
389
                                         int sid,
390
                                         const char *provider_name,
391 5dbafeb7 Fabrice Bellard
                                         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
407
static 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
413
static 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;
420 8b475508 Fabrice Bellard
    const char *service_name;
421 115329f1 Diego Biurrun
422 5dbafeb7 Fabrice Bellard
    ts->tsid = DEFAULT_TSID;
423
    ts->onid = DEFAULT_ONID;
424
    /* allocate a single DVB service */
425 8b475508 Fabrice Bellard
    service_name = s->title;
426
    if (service_name[0] == '\0')
427
        service_name = DEFAULT_SERVICE_NAME;
428 115329f1 Diego Biurrun
    service = mpegts_add_service(ts, DEFAULT_SID,
429 8b475508 Fabrice Bellard
                                 DEFAULT_PROVIDER_NAME, service_name);
430 5dbafeb7 Fabrice Bellard
    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;
451 8b475508 Fabrice Bellard
        ts_st->service = service;
452 5dbafeb7 Fabrice Bellard
        ts_st->pid = DEFAULT_START_PID + i;
453 69ef9450 Fabrice Bellard
        ts_st->payload_pts = AV_NOPTS_VALUE;
454 8b475508 Fabrice Bellard
        /* update PCR pid by using the first video stream */
455 115329f1 Diego Biurrun
        if (st->codec->codec_type == CODEC_TYPE_VIDEO &&
456 5dbafeb7 Fabrice Bellard
            service->pcr_pid == 0x1fff)
457
            service->pcr_pid = ts_st->pid;
458 01f4895c Michael Niedermayer
        total_bit_rate += st->codec->bit_rate;
459 5dbafeb7 Fabrice Bellard
    }
460 115329f1 Diego Biurrun
461 8b475508 Fabrice Bellard
    /* 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
467 5dbafeb7 Fabrice Bellard
    if (total_bit_rate <= 8 * 1024)
468
        total_bit_rate = 8 * 1024;
469 115329f1 Diego Biurrun
    service->pcr_packet_freq = (total_bit_rate * PCR_RETRANS_TIME) /
470 8b475508 Fabrice Bellard
        (TS_PACKET_SIZE * 8 * 1000);
471 115329f1 Diego Biurrun
    ts->sdt_packet_freq = (total_bit_rate * SDT_RETRANS_TIME) /
472 5dbafeb7 Fabrice Bellard
        (TS_PACKET_SIZE * 8 * 1000);
473 115329f1 Diego Biurrun
    ts->pat_packet_freq = (total_bit_rate * PAT_RETRANS_TIME) /
474 5dbafeb7 Fabrice Bellard
        (TS_PACKET_SIZE * 8 * 1000);
475
#if 0
476 115329f1 Diego Biurrun
    printf("%d %d %d\n",
477 5dbafeb7 Fabrice Bellard
           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 */
500
static 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
518 69ef9450 Fabrice Bellard
/* NOTE: pes_data contains all the PES packet */
519
static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
520
                             const uint8_t *payload, int payload_size,
521
                             int64_t pts)
522 5dbafeb7 Fabrice Bellard
{
523
    MpegTSWriteStream *ts_st = st->priv_data;
524 69ef9450 Fabrice Bellard
    uint8_t buf[TS_PACKET_SIZE];
525 5dbafeb7 Fabrice Bellard
    uint8_t *q;
526 8b475508 Fabrice Bellard
    int val, is_start, len, header_len, write_pcr, private_code;
527
    int afc_len, stuffing_len;
528
    int64_t pcr = -1; /* avoid warning */
529 5dbafeb7 Fabrice Bellard
530 69ef9450 Fabrice Bellard
    is_start = 1;
531
    while (payload_size > 0) {
532
        retransmit_si_info(s);
533 5dbafeb7 Fabrice Bellard
534 8b475508 Fabrice Bellard
        write_pcr = 0;
535
        if (ts_st->pid == ts_st->service->pcr_pid) {
536
            ts_st->service->pcr_packet_count++;
537 115329f1 Diego Biurrun
            if (ts_st->service->pcr_packet_count >=
538 8b475508 Fabrice Bellard
                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
547 69ef9450 Fabrice Bellard
        /* 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;
555 8b475508 Fabrice Bellard
        *q++ = 0x10 | ts_st->cc | (write_pcr ? 0x20 : 0);
556 69ef9450 Fabrice Bellard
        ts_st->cc = (ts_st->cc + 1) & 0xf;
557 8b475508 Fabrice Bellard
        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
        }
567 69ef9450 Fabrice Bellard
        if (is_start) {
568
            /* write PES header */
569
            *q++ = 0x00;
570
            *q++ = 0x00;
571
            *q++ = 0x01;
572 8b475508 Fabrice Bellard
            private_code = 0;
573 01f4895c Michael Niedermayer
            if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
574 69ef9450 Fabrice Bellard
                *q++ = 0xe0;
575 01f4895c Michael Niedermayer
            } 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)) {
578 115329f1 Diego Biurrun
                *q++ = 0xc0;
579 8b475508 Fabrice Bellard
            } else {
580
                *q++ = 0xbd;
581 01f4895c Michael Niedermayer
                if (st->codec->codec_type == CODEC_TYPE_SUBTITLE) {
582 8b475508 Fabrice Bellard
                    private_code = 0x20;
583
                }
584
            }
585 69ef9450 Fabrice Bellard
            if (pts != AV_NOPTS_VALUE)
586
                header_len = 8;
587
            else
588
                header_len = 3;
589 8b475508 Fabrice Bellard
            if (private_code != 0)
590
                header_len++;
591 69ef9450 Fabrice Bellard
            len = payload_size + header_len;
592
            *q++ = len >> 8;
593
            *q++ = len;
594 8b475508 Fabrice Bellard
            val = 0x80;
595
            /* data alignment indicator is required for subtitle data */
596 01f4895c Michael Niedermayer
            if (st->codec->codec_type == CODEC_TYPE_SUBTITLE)
597 8b475508 Fabrice Bellard
                val |= 0x04;
598
            *q++ = val;
599 69ef9450 Fabrice Bellard
            if (pts != AV_NOPTS_VALUE) {
600
                *q++ = 0x80; /* PTS only */
601
                *q++ = 0x05; /* header len */
602 115329f1 Diego Biurrun
                val = (0x02 << 4) |
603 69ef9450 Fabrice Bellard
                    (((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 {
612 5dbafeb7 Fabrice Bellard
                *q++ = 0x00;
613
                *q++ = 0x00;
614
            }
615 8b475508 Fabrice Bellard
            if (private_code != 0)
616
                *q++ = private_code;
617 69ef9450 Fabrice Bellard
            is_start = 0;
618 5dbafeb7 Fabrice Bellard
        }
619 8b475508 Fabrice Bellard
        /* header size */
620
        header_len = q - buf;
621
        /* data len */
622
        len = TS_PACKET_SIZE - header_len;
623 69ef9450 Fabrice Bellard
        if (len > payload_size)
624
            len = payload_size;
625 8b475508 Fabrice Bellard
        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 115329f1 Diego Biurrun
                        buf + 4 + afc_len,
633 8b475508 Fabrice Bellard
                        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);
648 69ef9450 Fabrice Bellard
        payload += len;
649
        payload_size -= len;
650 8b475508 Fabrice Bellard
        put_buffer(&s->pb, buf, TS_PACKET_SIZE);
651 5dbafeb7 Fabrice Bellard
    }
652
    put_flush_packet(&s->pb);
653 69ef9450 Fabrice Bellard
}
654
655 e928649b Michael Niedermayer
static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt)
656 69ef9450 Fabrice Bellard
{
657 e928649b Michael Niedermayer
    AVStream *st = s->streams[pkt->stream_index];
658
    int size= pkt->size;
659
    uint8_t *buf= pkt->data;
660 69ef9450 Fabrice Bellard
    MpegTSWriteStream *ts_st = st->priv_data;
661 8b475508 Fabrice Bellard
    int len, max_payload_size;
662 69ef9450 Fabrice Bellard
663 01f4895c Michael Niedermayer
    if (st->codec->codec_type == CODEC_TYPE_SUBTITLE) {
664 8b475508 Fabrice Bellard
        /* for subtitle, a single PES packet must be generated */
665
        mpegts_write_pes(s, st, buf, size, pkt->pts);
666
        return 0;
667
    }
668 115329f1 Diego Biurrun
669 8b475508 Fabrice Bellard
    max_payload_size = DEFAULT_PES_PAYLOAD_SIZE;
670 69ef9450 Fabrice Bellard
    while (size > 0) {
671 8b475508 Fabrice Bellard
        len = max_payload_size - ts_st->payload_index;
672 69ef9450 Fabrice Bellard
        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)
679 e928649b Michael Niedermayer
            ts_st->payload_pts = pkt->pts;
680 8b475508 Fabrice Bellard
        if (ts_st->payload_index >= max_payload_size) {
681 69ef9450 Fabrice Bellard
            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
    }
687 5dbafeb7 Fabrice Bellard
    return 0;
688
}
689
690
static 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;
702 69ef9450 Fabrice Bellard
        if (ts_st->payload_index > 0) {
703
            mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_index,
704
                             ts_st->payload_pts);
705 5dbafeb7 Fabrice Bellard
        }
706
    }
707
    put_flush_packet(&s->pb);
708 115329f1 Diego Biurrun
709 5dbafeb7 Fabrice Bellard
    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
717
    return 0;
718
}
719
720
AVOutputFormat mpegts_mux = {
721
    "mpegts",
722
    "MPEG2 transport stream format",
723
    "video/x-mpegts",
724
    "ts",
725
    sizeof(MpegTSWrite),
726
    CODEC_ID_MP2,
727 69ef9450 Fabrice Bellard
    CODEC_ID_MPEG2VIDEO,
728 5dbafeb7 Fabrice Bellard
    mpegts_write_header,
729
    mpegts_write_packet,
730
    mpegts_write_end,
731
};