Statistics
| Branch: | Revision:

ffmpeg / libavformat / mpegtsenc.c @ 34f633df

History | View | Annotate | Download (19.2 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
 * 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
25 49057904 Fabrice Bellard
static const uint32_t crc_table[256] = {
26 5dbafeb7 Fabrice Bellard
        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
71
unsigned 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
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
    
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
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
int 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
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
194
typedef struct MpegTSWriteStream {
195
    int pid; /* stream associated pid */
196
    int cc;
197 69ef9450 Fabrice Bellard
    int payload_index;
198
    int64_t payload_pts;
199
    uint8_t payload[DEFAULT_PES_PAYLOAD_SIZE];
200 5dbafeb7 Fabrice Bellard
} MpegTSWriteStream;
201
202
typedef struct MpegTSService {
203
    MpegTSSection pmt; /* MPEG2 pmt table context */
204
    int pcr_pid;
205
    int sid;           /* service ID */
206
    char *name;
207
    char *provider_name;
208
} MpegTSService;
209
210
typedef struct MpegTSWrite {
211
    MpegTSSection pat; /* MPEG2 pat table */
212
    MpegTSSection sdt; /* MPEG2 sdt table context */
213
    MpegTSService **services;
214
    int sdt_packet_count;
215
    int sdt_packet_freq;
216
    int pat_packet_count;
217
    int pat_packet_freq;
218
    int nb_services;
219
    int onid;
220
    int tsid;
221
} MpegTSWrite;
222
223
static void mpegts_write_pat(AVFormatContext *s)
224
{
225
    MpegTSWrite *ts = s->priv_data;
226
    MpegTSService *service;
227
    uint8_t data[1012], *q;
228
    int i;
229
    
230
    q = data;
231
    for(i = 0; i < ts->nb_services; i++) {
232
        service = ts->services[i];
233
        put16(&q, service->sid);
234
        put16(&q, 0xe000 | service->pmt.pid);
235
    }
236
    mpegts_write_section1(&ts->pat, PAT_TID, ts->tsid, 0, 0, 0,
237
                          data, q - data);
238
}
239
240
static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
241
{
242
    //    MpegTSWrite *ts = s->priv_data;
243
    uint8_t data[1012], *q, *desc_length_ptr, *program_info_length_ptr;
244
    int val, stream_type, i;
245
246
    q = data;
247
    put16(&q, 0xe000 | service->pcr_pid);
248
249
    program_info_length_ptr = q;
250
    q += 2; /* patched after */
251
252
    /* put program info here */
253
254
    val = 0xf000 | (q - program_info_length_ptr - 2);
255
    program_info_length_ptr[0] = val >> 8;
256
    program_info_length_ptr[1] = val;
257
    
258
    for(i = 0; i < s->nb_streams; i++) {
259
        AVStream *st = s->streams[i];
260
        MpegTSWriteStream *ts_st = st->priv_data;
261 278de475 Måns Rullgård
        switch(st->codec.codec_id) {
262
        case CODEC_ID_MPEG1VIDEO:
263
        case CODEC_ID_MPEG2VIDEO:
264
            stream_type = STREAM_TYPE_VIDEO_MPEG2;
265 5dbafeb7 Fabrice Bellard
            break;
266 278de475 Måns Rullgård
        case CODEC_ID_MPEG4:
267
            stream_type = STREAM_TYPE_VIDEO_MPEG4;
268
            break;
269
        case CODEC_ID_H264:
270
            stream_type = STREAM_TYPE_VIDEO_H264;
271
            break;
272
        case CODEC_ID_MP2:
273
        case CODEC_ID_MP3:
274 ce34182d Michael Niedermayer
            stream_type = STREAM_TYPE_AUDIO_MPEG1;
275 5dbafeb7 Fabrice Bellard
            break;
276 278de475 Måns Rullgård
        case CODEC_ID_AAC:
277
            stream_type = STREAM_TYPE_AUDIO_AAC;
278
            break;
279
        case CODEC_ID_AC3:
280
            stream_type = STREAM_TYPE_AUDIO_AC3;
281
            break;
282 5dbafeb7 Fabrice Bellard
        default:
283
            stream_type = STREAM_TYPE_PRIVATE_DATA;
284
            break;
285
        }
286
        *q++ = stream_type;
287
        put16(&q, 0xe000 | ts_st->pid);
288
        desc_length_ptr = q;
289
        q += 2; /* patched after */
290
291
        /* write optional descriptors here */
292
293
        val = 0xf000 | (q - desc_length_ptr - 2);
294
        desc_length_ptr[0] = val >> 8;
295
        desc_length_ptr[1] = val;
296
    }
297
    mpegts_write_section1(&service->pmt, PMT_TID, service->sid, 0, 0, 0,
298
                          data, q - data);
299
}   
300
301
/* NOTE: str == NULL is accepted for an empty string */
302
static void putstr8(uint8_t **q_ptr, const char *str)
303
{
304
    uint8_t *q;
305
    int len;
306
307
    q = *q_ptr;
308
    if (!str)
309
        len = 0;
310
    else
311
        len = strlen(str);
312
    *q++ = len;
313
    memcpy(q, str, len);
314
    q += len;
315
    *q_ptr = q;
316
}
317
318
static void mpegts_write_sdt(AVFormatContext *s)
319
{
320
    MpegTSWrite *ts = s->priv_data;
321
    MpegTSService *service;
322
    uint8_t data[1012], *q, *desc_list_len_ptr, *desc_len_ptr;
323
    int i, running_status, free_ca_mode, val;
324
    
325
    q = data;
326
    put16(&q, ts->onid);
327
    *q++ = 0xff;
328
    for(i = 0; i < ts->nb_services; i++) {
329
        service = ts->services[i];
330
        put16(&q, service->sid);
331
        *q++ = 0xfc | 0x00; /* currently no EIT info */
332
        desc_list_len_ptr = q;
333
        q += 2;
334
        running_status = 4; /* running */
335
        free_ca_mode = 0;
336
337
        /* write only one descriptor for the service name and provider */
338
        *q++ = 0x48;
339
        desc_len_ptr = q;
340
        q++;
341
        *q++ = 0x01; /* digital television service */
342
        putstr8(&q, service->provider_name);
343
        putstr8(&q, service->name);
344
        desc_len_ptr[0] = q - desc_len_ptr - 1;
345
346
        /* fill descriptor length */
347
        val = (running_status << 13) | (free_ca_mode << 12) | 
348
            (q - desc_list_len_ptr - 2);
349
        desc_list_len_ptr[0] = val >> 8;
350
        desc_list_len_ptr[1] = val;
351
    }
352
    mpegts_write_section1(&ts->sdt, SDT_TID, ts->tsid, 0, 0, 0,
353
                          data, q - data);
354
}
355
356
static MpegTSService *mpegts_add_service(MpegTSWrite *ts, 
357
                                         int sid, 
358
                                         const char *provider_name, 
359
                                         const char *name)
360
{
361
    MpegTSService *service;
362
363
    service = av_mallocz(sizeof(MpegTSService));
364
    if (!service)
365
        return NULL;
366
    service->pmt.pid = DEFAULT_PMT_START_PID + ts->nb_services - 1;
367
    service->sid = sid;
368
    service->provider_name = av_strdup(provider_name);
369
    service->name = av_strdup(name);
370
    service->pcr_pid = 0x1fff;
371
    dynarray_add(&ts->services, &ts->nb_services, service);
372
    return service;
373
}
374
375
static void section_write_packet(MpegTSSection *s, const uint8_t *packet)
376
{
377
    AVFormatContext *ctx = s->opaque;
378
    put_buffer(&ctx->pb, packet, TS_PACKET_SIZE);
379
}
380
381
static int mpegts_write_header(AVFormatContext *s)
382
{
383
    MpegTSWrite *ts = s->priv_data;
384
    MpegTSWriteStream *ts_st;
385
    MpegTSService *service;
386
    AVStream *st;
387
    int i, total_bit_rate;
388
389
    ts->tsid = DEFAULT_TSID;
390
    ts->onid = DEFAULT_ONID;
391
    /* allocate a single DVB service */
392
    service = mpegts_add_service(ts, DEFAULT_SID, 
393
                                 DEFAULT_PROVIDER_NAME, DEFAULT_SERVICE_NAME);
394
    service->pmt.write_packet = section_write_packet;
395
    service->pmt.opaque = s;
396
397
    ts->pat.pid = PAT_PID;
398
    ts->pat.cc = 0;
399
    ts->pat.write_packet = section_write_packet;
400
    ts->pat.opaque = s;
401
402
    ts->sdt.pid = SDT_PID;
403
    ts->sdt.cc = 0;
404
    ts->sdt.write_packet = section_write_packet;
405
    ts->sdt.opaque = s;
406
407
    /* assign pids to each stream */
408
    total_bit_rate = 0;
409
    for(i = 0;i < s->nb_streams; i++) {
410
        st = s->streams[i];
411
        ts_st = av_mallocz(sizeof(MpegTSWriteStream));
412
        if (!ts_st)
413
            goto fail;
414
        st->priv_data = ts_st;
415
        ts_st->pid = DEFAULT_START_PID + i;
416 69ef9450 Fabrice Bellard
        ts_st->payload_pts = AV_NOPTS_VALUE;
417 5dbafeb7 Fabrice Bellard
        /* update PCR pid if needed */
418
        if (st->codec.codec_type == CODEC_TYPE_VIDEO && 
419
            service->pcr_pid == 0x1fff)
420
            service->pcr_pid = ts_st->pid;
421
        total_bit_rate += st->codec.bit_rate;
422
    }
423
    if (total_bit_rate <= 8 * 1024)
424
        total_bit_rate = 8 * 1024;
425
    ts->sdt_packet_freq = (total_bit_rate * SDT_RETRANS_TIME) / 
426
        (TS_PACKET_SIZE * 8 * 1000);
427
    ts->pat_packet_freq = (total_bit_rate * PAT_RETRANS_TIME) / 
428
        (TS_PACKET_SIZE * 8 * 1000);
429
#if 0
430
    printf("%d %d %d\n", 
431
           total_bit_rate, ts->sdt_packet_freq, ts->pat_packet_freq);
432
#endif
433
434
    /* write info at the start of the file, so that it will be fast to
435
       find them */
436
    mpegts_write_sdt(s);
437
    mpegts_write_pat(s);
438
    for(i = 0; i < ts->nb_services; i++) {
439
        mpegts_write_pmt(s, ts->services[i]);
440
    }
441
    put_flush_packet(&s->pb);
442
443
    return 0;
444
445
 fail:
446
    for(i = 0;i < s->nb_streams; i++) {
447
        st = s->streams[i];
448
        av_free(st->priv_data);
449
    }
450
    return -1;
451
}
452
453
/* send SDT, PAT and PMT tables regulary */
454
static void retransmit_si_info(AVFormatContext *s)
455
{
456
    MpegTSWrite *ts = s->priv_data;
457
    int i;
458
459
    if (++ts->sdt_packet_count == ts->sdt_packet_freq) {
460
        ts->sdt_packet_count = 0;
461
        mpegts_write_sdt(s);
462
    }
463
    if (++ts->pat_packet_count == ts->pat_packet_freq) {
464
        ts->pat_packet_count = 0;
465
        mpegts_write_pat(s);
466
        for(i = 0; i < ts->nb_services; i++) {
467
            mpegts_write_pmt(s, ts->services[i]);
468
        }
469
    }
470
}
471
472 69ef9450 Fabrice Bellard
/* NOTE: pes_data contains all the PES packet */
473
static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
474
                             const uint8_t *payload, int payload_size,
475
                             int64_t pts)
476 5dbafeb7 Fabrice Bellard
{
477
    MpegTSWriteStream *ts_st = st->priv_data;
478 69ef9450 Fabrice Bellard
    uint8_t buf[TS_PACKET_SIZE];
479 5dbafeb7 Fabrice Bellard
    uint8_t *q;
480 69ef9450 Fabrice Bellard
    int val, is_start, len, ts_len, header_len;
481 5dbafeb7 Fabrice Bellard
482 69ef9450 Fabrice Bellard
    is_start = 1;
483
    while (payload_size > 0) {
484
        retransmit_si_info(s);
485 5dbafeb7 Fabrice Bellard
486 69ef9450 Fabrice Bellard
        /* prepare packet header */
487
        q = buf;
488
        *q++ = 0x47;
489
        val = (ts_st->pid >> 8);
490
        if (is_start)
491
            val |= 0x40;
492
        *q++ = val;
493
        *q++ = ts_st->pid;
494
        *q++ = 0x10 | ts_st->cc;
495
        ts_st->cc = (ts_st->cc + 1) & 0xf;
496
        if (is_start) {
497
            /* write PES header */
498
            *q++ = 0x00;
499
            *q++ = 0x00;
500
            *q++ = 0x01;
501
            if (st->codec.codec_type == CODEC_TYPE_VIDEO)
502
                *q++ = 0xe0;
503
            else
504
                *q++ = 0xc0;
505
            if (pts != AV_NOPTS_VALUE)
506
                header_len = 8;
507
            else
508
                header_len = 3;
509
            len = payload_size + header_len;
510
            *q++ = len >> 8;
511
            *q++ = len;
512
            *q++ = 0x80;
513
            if (pts != AV_NOPTS_VALUE) {
514
                *q++ = 0x80; /* PTS only */
515
                *q++ = 0x05; /* header len */
516
                val = (0x02 << 4) | 
517
                    (((pts >> 30) & 0x07) << 1) | 1;
518
                *q++ = val;
519
                val = (((pts >> 15) & 0x7fff) << 1) | 1;
520
                *q++ = val >> 8;
521
                *q++ = val;
522
                val = (((pts) & 0x7fff) << 1) | 1;
523
                *q++ = val >> 8;
524
                *q++ = val;
525
            } else {
526 5dbafeb7 Fabrice Bellard
                *q++ = 0x00;
527
                *q++ = 0x00;
528
            }
529 69ef9450 Fabrice Bellard
            is_start = 0;
530 5dbafeb7 Fabrice Bellard
        }
531 69ef9450 Fabrice Bellard
        /* write header */
532
        ts_len = q - buf;
533
        put_buffer(&s->pb, buf, ts_len);
534
        /* write data */
535
        len = TS_PACKET_SIZE - ts_len;
536
        if (len > payload_size)
537
            len = payload_size;
538
        put_buffer(&s->pb, payload, len);
539
        payload += len;
540
        payload_size -= len;
541
        ts_len += len;
542
        /* stuffing */
543
        len = TS_PACKET_SIZE - ts_len;
544
        if (len > 0) {
545
            memset(buf, 0xff, len);
546
            put_buffer(&s->pb, buf, len);
547 5dbafeb7 Fabrice Bellard
        }
548
    }
549
    put_flush_packet(&s->pb);
550 69ef9450 Fabrice Bellard
}
551
552 e928649b Michael Niedermayer
static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt)
553 69ef9450 Fabrice Bellard
{
554 e928649b Michael Niedermayer
    AVStream *st = s->streams[pkt->stream_index];
555
    int size= pkt->size;
556
    uint8_t *buf= pkt->data;
557 69ef9450 Fabrice Bellard
    MpegTSWriteStream *ts_st = st->priv_data;
558
    int len;
559
560
    while (size > 0) {
561
        len = DEFAULT_PES_PAYLOAD_SIZE - ts_st->payload_index;
562
        if (len > size)
563
            len = size;
564
        memcpy(ts_st->payload + ts_st->payload_index, buf, len);
565
        buf += len;
566
        size -= len;
567
        ts_st->payload_index += len;
568
        if (ts_st->payload_pts == AV_NOPTS_VALUE)
569 e928649b Michael Niedermayer
            ts_st->payload_pts = pkt->pts;
570 69ef9450 Fabrice Bellard
        if (ts_st->payload_index >= DEFAULT_PES_PAYLOAD_SIZE) {
571
            mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_index,
572
                             ts_st->payload_pts);
573
            ts_st->payload_pts = AV_NOPTS_VALUE;
574
            ts_st->payload_index = 0;
575
        }
576
    }
577 5dbafeb7 Fabrice Bellard
    return 0;
578
}
579
580
static int mpegts_write_end(AVFormatContext *s)
581
{
582
    MpegTSWrite *ts = s->priv_data;
583
    MpegTSWriteStream *ts_st;
584
    MpegTSService *service;
585
    AVStream *st;
586
    int i;
587
588
    /* flush current packets */
589
    for(i = 0; i < s->nb_streams; i++) {
590
        st = s->streams[i];
591
        ts_st = st->priv_data;
592 69ef9450 Fabrice Bellard
        if (ts_st->payload_index > 0) {
593
            mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_index,
594
                             ts_st->payload_pts);
595 5dbafeb7 Fabrice Bellard
        }
596
    }
597
    put_flush_packet(&s->pb);
598
        
599
    for(i = 0; i < ts->nb_services; i++) {
600
        service = ts->services[i];
601
        av_freep(&service->provider_name);
602
        av_freep(&service->name);
603
        av_free(service);
604
    }
605
    av_free(ts->services);
606
607
    return 0;
608
}
609
610
AVOutputFormat mpegts_mux = {
611
    "mpegts",
612
    "MPEG2 transport stream format",
613
    "video/x-mpegts",
614
    "ts",
615
    sizeof(MpegTSWrite),
616
    CODEC_ID_MP2,
617 69ef9450 Fabrice Bellard
    CODEC_ID_MPEG2VIDEO,
618 5dbafeb7 Fabrice Bellard
    mpegts_write_header,
619
    mpegts_write_packet,
620
    mpegts_write_end,
621
};