mpegtsenc.c 40.2 KB
Newer Older
1
/*
2
 * MPEG2 transport stream (aka DVB) muxer
3
 * Copyright (c) 2003 Fabrice Bellard
4
 *
5
 * This file is part of Libav.
6
 *
7
 * Libav is free software; you can redistribute it and/or
8 9
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * Libav is distributed in the hope that it will be useful,
13 14 15 16 17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with Libav; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21

22
#include "libavutil/bswap.h"
23
#include "libavutil/crc.h"
24
#include "libavutil/dict.h"
25
#include "libavutil/intreadwrite.h"
26
#include "libavutil/mathematics.h"
27
#include "libavutil/opt.h"
D
Diego Biurrun 已提交
28

29
#include "libavcodec/internal.h"
D
Diego Biurrun 已提交
30

31
#include "avformat.h"
32
#include "internal.h"
33 34
#include "mpegts.h"

35 36
#define PCR_TIME_BASE 27000000

37 38 39 40 41 42 43 44 45 46 47 48
/* write DVB SI sections */

/*********************************************/
/* mpegts section writer */

typedef struct MpegTSSection {
    int pid;
    int cc;
    void (*write_packet)(struct MpegTSSection *s, const uint8_t *packet);
    void *opaque;
} MpegTSSection;

49 50 51 52 53 54 55
typedef struct MpegTSService {
    MpegTSSection pmt; /* MPEG2 pmt table context */
    int sid;           /* service ID */
    char *name;
    char *provider_name;
    int pcr_pid;
    int pcr_packet_count;
56
    int pcr_packet_period;
57 58 59
} MpegTSService;

typedef struct MpegTSWrite {
60
    const AVClass *av_class;
61 62 63 64
    MpegTSSection pat; /* MPEG2 pat table */
    MpegTSSection sdt; /* MPEG2 sdt table context */
    MpegTSService **services;
    int sdt_packet_count;
65
    int sdt_packet_period;
66
    int pat_packet_count;
67
    int pat_packet_period;
68 69 70
    int nb_services;
    int onid;
    int tsid;
71
    int64_t first_pcr;
72
    int mux_rate; ///< set to 1 when VBR
73
    int pes_payload_size;
74 75 76 77 78 79 80

    int transport_stream_id;
    int original_network_id;
    int service_id;

    int pmt_start_pid;
    int start_pid;
81

82 83
    int reemit_pat_pmt; // backward compatibility

84
    int pcr_period;
85 86 87
#define MPEGTS_FLAG_REEMIT_PAT_PMT  0x01
#define MPEGTS_FLAG_AAC_LATM        0x02
    int flags;
88 89
} MpegTSWrite;

90
/* a PES packet header is generated every DEFAULT_PES_HEADER_FREQ packets */
D
Diego Biurrun 已提交
91
#define DEFAULT_PES_HEADER_FREQ  16
92 93
#define DEFAULT_PES_PAYLOAD_SIZE ((DEFAULT_PES_HEADER_FREQ - 1) * 184 + 170)

94 95 96 97
/* The section length is 12 bits. The first 2 are set to 0, the remaining
 * 10 bits should not exceed 1021. */
#define SECTION_LENGTH 1020

98
/* NOTE: 4 bytes must be left at the end for the crc32 */
99
static void mpegts_write_section(MpegTSSection *s, uint8_t *buf, int len)
100 101 102 103 104 105 106
{
    unsigned int crc;
    unsigned char packet[TS_PACKET_SIZE];
    const unsigned char *buf_ptr;
    unsigned char *q;
    int first, b, len1, left;

D
Diego Biurrun 已提交
107 108 109
    crc = av_bswap32(av_crc(av_crc_get_table(AV_CRC_32_IEEE),
                            -1, buf, len - 4));

110 111
    buf[len - 4] = (crc >> 24) & 0xff;
    buf[len - 3] = (crc >> 16) & 0xff;
D
Diego Biurrun 已提交
112
    buf[len - 2] = (crc >>  8) & 0xff;
113
    buf[len - 1] =  crc        & 0xff;
114

115 116 117
    /* send each packet */
    buf_ptr = buf;
    while (len > 0) {
118
        first = buf == buf_ptr;
D
Diego Biurrun 已提交
119 120
        q     = packet;
        *q++  = 0x47;
121
        b     = s->pid >> 8;
122 123
        if (first)
            b |= 0x40;
D
Diego Biurrun 已提交
124 125
        *q++  = b;
        *q++  = s->pid;
126
        s->cc = s->cc + 1 & 0xf;
D
Diego Biurrun 已提交
127
        *q++  = 0x10 | s->cc;
128 129 130
        if (first)
            *q++ = 0; /* 0 offset */
        len1 = TS_PACKET_SIZE - (q - packet);
131
        if (len1 > len)
132 133 134 135 136 137 138 139 140 141 142
            len1 = len;
        memcpy(q, buf_ptr, len1);
        q += len1;
        /* add known padding data */
        left = TS_PACKET_SIZE - (q - packet);
        if (left > 0)
            memset(q, 0xff, left);

        s->write_packet(s, packet);

        buf_ptr += len1;
D
Diego Biurrun 已提交
143
        len     -= len1;
144 145 146 147 148 149
    }
}

static inline void put16(uint8_t **q_ptr, int val)
{
    uint8_t *q;
D
Diego Biurrun 已提交
150 151 152
    q      = *q_ptr;
    *q++   = val >> 8;
    *q++   = val;
153 154 155
    *q_ptr = q;
}

156
static int mpegts_write_section1(MpegTSSection *s, int tid, int id,
D
Diego Biurrun 已提交
157 158
                                 int version, int sec_num, int last_sec_num,
                                 uint8_t *buf, int len)
159 160 161
{
    uint8_t section[1024], *q;
    unsigned int tot_len;
162 163
    /* reserved_future_use field must be set to 1 for SDT */
    unsigned int flags = tid == SDT_TID ? 0xf000 : 0xb000;
164

165 166 167
    tot_len = 3 + 5 + len + 4;
    /* check if not too big */
    if (tot_len > 1024)
168
        return AVERROR_INVALIDDATA;
169

D
Diego Biurrun 已提交
170
    q    = section;
171
    *q++ = tid;
172
    put16(&q, flags | (len + 5 + 4)); /* 5 byte header + 4 byte CRC */
173 174 175 176 177
    put16(&q, id);
    *q++ = 0xc1 | (version << 1); /* current_next_indicator = 1 */
    *q++ = sec_num;
    *q++ = last_sec_num;
    memcpy(q, buf, len);
178

179 180 181 182 183 184 185
    mpegts_write_section(s, section, tot_len);
    return 0;
}

/*********************************************/
/* mpegts writer */

186
#define DEFAULT_PROVIDER_NAME   "Libav"
187 188 189 190 191
#define DEFAULT_SERVICE_NAME    "Service01"

/* we retransmit the SI info at this rate */
#define SDT_RETRANS_TIME 500
#define PAT_RETRANS_TIME 100
192
#define PCR_RETRANS_TIME 20
193 194

typedef struct MpegTSWriteStream {
195
    struct MpegTSService *service;
196 197
    int pid; /* stream associated pid */
    int cc;
198
    int payload_size;
199
    int first_pts_check; ///< first pts check needed
200
    int64_t payload_pts;
201
    int64_t payload_dts;
202
    int payload_flags;
203
    uint8_t *payload;
204
    AVFormatContext *amux;
205
    AVRational user_tb;
206 207 208 209 210 211
} MpegTSWriteStream;

static void mpegts_write_pat(AVFormatContext *s)
{
    MpegTSWrite *ts = s->priv_data;
    MpegTSService *service;
212
    uint8_t data[SECTION_LENGTH], *q;
213
    int i;
214

215
    q = data;
D
Diego Biurrun 已提交
216
    for (i = 0; i < ts->nb_services; i++) {
217 218 219 220 221 222 223 224 225 226
        service = ts->services[i];
        put16(&q, service->sid);
        put16(&q, 0xe000 | service->pmt.pid);
    }
    mpegts_write_section1(&ts->pat, PAT_TID, ts->tsid, 0, 0, 0,
                          data, q - data);
}

static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
{
227
    MpegTSWrite *ts = s->priv_data;
228
    uint8_t data[SECTION_LENGTH], *q, *desc_length_ptr, *program_info_length_ptr;
229
    int val, stream_type, i, err = 0;
230 231 232 233 234 235 236 237 238 239 240 241

    q = data;
    put16(&q, 0xe000 | service->pcr_pid);

    program_info_length_ptr = q;
    q += 2; /* patched after */

    /* put program info here */

    val = 0xf000 | (q - program_info_length_ptr - 2);
    program_info_length_ptr[0] = val >> 8;
    program_info_length_ptr[1] = val;
242

D
Diego Biurrun 已提交
243
    for (i = 0; i < s->nb_streams; i++) {
244 245
        AVStream *st = s->streams[i];
        MpegTSWriteStream *ts_st = st->priv_data;
D
Diego Biurrun 已提交
246
        AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0);
247 248 249 250 251

        if (q - data > SECTION_LENGTH - 3 - 2 - 6) {
            err = 1;
            break;
        }
D
Diego Biurrun 已提交
252
        switch (st->codec->codec_id) {
253 254
        case AV_CODEC_ID_MPEG1VIDEO:
        case AV_CODEC_ID_MPEG2VIDEO:
255
            stream_type = STREAM_TYPE_VIDEO_MPEG2;
256
            break;
257
        case AV_CODEC_ID_MPEG4:
258 259
            stream_type = STREAM_TYPE_VIDEO_MPEG4;
            break;
260
        case AV_CODEC_ID_H264:
261 262
            stream_type = STREAM_TYPE_VIDEO_H264;
            break;
263 264 265
        case AV_CODEC_ID_HEVC:
            stream_type = STREAM_TYPE_VIDEO_HEVC;
            break;
266 267 268
        case AV_CODEC_ID_CAVS:
            stream_type = STREAM_TYPE_VIDEO_CAVS;
            break;
269
        case AV_CODEC_ID_DIRAC:
270 271
            stream_type = STREAM_TYPE_VIDEO_DIRAC;
            break;
272 273
        case AV_CODEC_ID_MP2:
        case AV_CODEC_ID_MP3:
274
            stream_type = STREAM_TYPE_AUDIO_MPEG1;
275
            break;
276
        case AV_CODEC_ID_AAC:
D
Diego Biurrun 已提交
277 278 279
            stream_type = (ts->flags & MPEGTS_FLAG_AAC_LATM)
                          ? STREAM_TYPE_AUDIO_AAC_LATM
                          : STREAM_TYPE_AUDIO_AAC;
280
            break;
281
        case AV_CODEC_ID_AAC_LATM:
282 283
            stream_type = STREAM_TYPE_AUDIO_AAC_LATM;
            break;
284
        case AV_CODEC_ID_AC3:
285
            stream_type = STREAM_TYPE_AUDIO_AC3;
286
            break;
287 288 289 290 291 292 293 294 295 296
        default:
            stream_type = STREAM_TYPE_PRIVATE_DATA;
            break;
        }
        *q++ = stream_type;
        put16(&q, 0xe000 | ts_st->pid);
        desc_length_ptr = q;
        q += 2; /* patched after */

        /* write optional descriptors here */
D
Diego Biurrun 已提交
297
        switch (st->codec->codec_type) {
298
        case AVMEDIA_TYPE_AUDIO:
299 300 301 302 303
            if (lang) {
                char *p;
                char *next = lang->value;
                uint8_t *len_ptr;

D
Diego Biurrun 已提交
304 305
                *q++     = 0x0a; /* ISO 639 language descriptor */
                len_ptr  = q++;
306 307 308
                *len_ptr = 0;

                for (p = lang->value; next && *len_ptr < 255 / 4 * 4; p = next + 1) {
309 310 311 312
                    if (q - data > SECTION_LENGTH - 4) {
                        err = 1;
                        break;
                    }
313 314 315 316 317 318 319 320
                    next = strchr(p, ',');
                    if (strlen(p) != 3 && (!next || next != p + 3))
                        continue; /* not a 3-letter code */

                    *q++ = *p++;
                    *q++ = *p++;
                    *q++ = *p++;

D
Diego Biurrun 已提交
321 322 323 324 325 326 327 328
                    if (st->disposition & AV_DISPOSITION_CLEAN_EFFECTS)
                        *q++ = 0x01;
                    else if (st->disposition & AV_DISPOSITION_HEARING_IMPAIRED)
                        *q++ = 0x02;
                    else if (st->disposition & AV_DISPOSITION_VISUAL_IMPAIRED)
                        *q++ = 0x03;
                    else
                        *q++ = 0; /* undefined type */
329 330 331 332 333 334

                    *len_ptr += 4;
                }

                if (*len_ptr == 0)
                    q -= 2; /* no language codes were written */
335 336
            }
            break;
337
        case AVMEDIA_TYPE_SUBTITLE:
D
Diego Biurrun 已提交
338 339 340 341 342 343 344 345 346
        {
            const char *language;
            language = lang && strlen(lang->value) == 3 ? lang->value : "eng";
            *q++ = 0x59;
            *q++ = 8;
            *q++ = language[0];
            *q++ = language[1];
            *q++ = language[2];
            *q++ = 0x10; /* normal subtitles (0x20 = if hearing pb) */
347 348 349 350 351 352

            if (q - data > SECTION_LENGTH - 4) {
                err = 1;
                break;
            }

D
Diego Biurrun 已提交
353 354 355 356 357 358
            if (st->codec->extradata_size == 4) {
                memcpy(q, st->codec->extradata, 4);
                q += 4;
            } else {
                put16(&q, 1);     /* page id */
                put16(&q, 1);     /* ancillary page id */
359
            }
D
Diego Biurrun 已提交
360 361
        }
        break;
362
        case AVMEDIA_TYPE_VIDEO:
363 364 365 366 367 368 369 370 371
            if (stream_type == STREAM_TYPE_VIDEO_DIRAC) {
                *q++ = 0x05; /*MPEG-2 registration descriptor*/
                *q++ = 4;
                *q++ = 'd';
                *q++ = 'r';
                *q++ = 'a';
                *q++ = 'c';
            }
            break;
372
        }
373 374 375 376 377

        val = 0xf000 | (q - desc_length_ptr - 2);
        desc_length_ptr[0] = val >> 8;
        desc_length_ptr[1] = val;
    }
378 379 380 381 382 383 384

    if (err)
        av_log(s, AV_LOG_ERROR,
               "The PMT section cannot fit stream %d and all following streams.\n"
               "Try reducing the number of languages in the audio streams "
               "or the total number of streams.\n", i);

385 386
    mpegts_write_section1(&service->pmt, PMT_TID, service->sid, 0, 0, 0,
                          data, q - data);
387
}
388 389 390 391 392 393 394 395 396 397 398 399 400 401

/* NOTE: str == NULL is accepted for an empty string */
static void putstr8(uint8_t **q_ptr, const char *str)
{
    uint8_t *q;
    int len;

    q = *q_ptr;
    if (!str)
        len = 0;
    else
        len = strlen(str);
    *q++ = len;
    memcpy(q, str, len);
D
Diego Biurrun 已提交
402
    q     += len;
403 404 405 406 407 408 409
    *q_ptr = q;
}

static void mpegts_write_sdt(AVFormatContext *s)
{
    MpegTSWrite *ts = s->priv_data;
    MpegTSService *service;
410
    uint8_t data[SECTION_LENGTH], *q, *desc_list_len_ptr, *desc_len_ptr;
411
    int i, running_status, free_ca_mode, val;
412

413 414 415
    q = data;
    put16(&q, ts->onid);
    *q++ = 0xff;
D
Diego Biurrun 已提交
416
    for (i = 0; i < ts->nb_services; i++) {
417 418
        service = ts->services[i];
        put16(&q, service->sid);
D
Diego Biurrun 已提交
419
        *q++              = 0xfc | 0x00; /* currently no EIT info */
420
        desc_list_len_ptr = q;
D
Diego Biurrun 已提交
421 422 423
        q                += 2;
        running_status    = 4; /* running */
        free_ca_mode      = 0;
424 425

        /* write only one descriptor for the service name and provider */
D
Diego Biurrun 已提交
426
        *q++         = 0x48;
427 428
        desc_len_ptr = q;
        q++;
D
Diego Biurrun 已提交
429
        *q++         = 0x01; /* digital television service */
430 431 432 433 434
        putstr8(&q, service->provider_name);
        putstr8(&q, service->name);
        desc_len_ptr[0] = q - desc_len_ptr - 1;

        /* fill descriptor length */
435
        val = (running_status << 13) | (free_ca_mode << 12) |
D
Diego Biurrun 已提交
436
              (q - desc_list_len_ptr - 2);
437 438 439 440 441 442 443
        desc_list_len_ptr[0] = val >> 8;
        desc_list_len_ptr[1] = val;
    }
    mpegts_write_section1(&ts->sdt, SDT_TID, ts->tsid, 0, 0, 0,
                          data, q - data);
}

D
Diego Biurrun 已提交
444
static MpegTSService *mpegts_add_service(MpegTSWrite *ts, int sid,
445
                                         const char *provider_name,
446 447 448 449 450 451 452
                                         const char *name)
{
    MpegTSService *service;

    service = av_mallocz(sizeof(MpegTSService));
    if (!service)
        return NULL;
D
Diego Biurrun 已提交
453 454
    service->pmt.pid       = ts->pmt_start_pid + ts->nb_services;
    service->sid           = sid;
455
    service->pcr_pid       = 0x1fff;
456
    service->provider_name = av_strdup(provider_name);
D
Diego Biurrun 已提交
457
    service->name          = av_strdup(name);
458
    if (!service->provider_name || !service->name) {
459 460 461
        av_free(service->provider_name);
        av_free(service->name);
        av_free(service);
462 463
        return NULL;
    }
464 465 466 467 468 469 470
    dynarray_add(&ts->services, &ts->nb_services, service);
    return service;
}

static void section_write_packet(MpegTSSection *s, const uint8_t *packet)
{
    AVFormatContext *ctx = s->opaque;
471
    avio_write(ctx->pb, packet, TS_PACKET_SIZE);
472 473 474 475 476 477 478
}

static int mpegts_write_header(AVFormatContext *s)
{
    MpegTSWrite *ts = s->priv_data;
    MpegTSWriteStream *ts_st;
    MpegTSService *service;
479
    AVStream *st, *pcr_st = NULL;
480
    AVDictionaryEntry *title, *provider;
481
    int i, j;
482
    const char *service_name;
483
    const char *provider_name;
484
    int *pids;
485
    int ret;
486

487 488 489
    if (s->max_delay < 0) /* Not set by the caller */
        s->max_delay = 0;

490 491 492
    // round up to a whole number of TS packets
    ts->pes_payload_size = (ts->pes_payload_size + 14 + 183) / 184 * 184 - 14;

493 494
    ts->tsid = ts->transport_stream_id;
    ts->onid = ts->original_network_id;
495
    /* allocate a single DVB service */
496
    title = av_dict_get(s->metadata, "service_name", NULL, 0);
497
    if (!title)
498
        title = av_dict_get(s->metadata, "title", NULL, 0);
D
Diego Biurrun 已提交
499 500
    service_name  = title ? title->value : DEFAULT_SERVICE_NAME;
    provider      = av_dict_get(s->metadata, "service_provider", NULL, 0);
501
    provider_name = provider ? provider->value : DEFAULT_PROVIDER_NAME;
D
Diego Biurrun 已提交
502 503 504
    service       = mpegts_add_service(ts, ts->service_id,
                                       provider_name, service_name);

505 506 507
    if (!service)
        return AVERROR(ENOMEM);

508
    service->pmt.write_packet = section_write_packet;
D
Diego Biurrun 已提交
509 510
    service->pmt.opaque       = s;
    service->pmt.cc           = 15;
511

D
Diego Biurrun 已提交
512 513 514 515
    ts->pat.pid          = PAT_PID;
    /* Initialize at 15 so that it wraps and is equal to 0 for the
     * first packet we write. */
    ts->pat.cc           = 15;
516
    ts->pat.write_packet = section_write_packet;
D
Diego Biurrun 已提交
517
    ts->pat.opaque       = s;
518

D
Diego Biurrun 已提交
519 520
    ts->sdt.pid          = SDT_PID;
    ts->sdt.cc           = 15;
521
    ts->sdt.write_packet = section_write_packet;
D
Diego Biurrun 已提交
522
    ts->sdt.opaque       = s;
523

524
    pids = av_malloc(s->nb_streams * sizeof(*pids));
525 526
    if (!pids) {
        av_free(service);
527
        return AVERROR(ENOMEM);
528
    }
529

530
    /* assign pids to each stream */
D
Diego Biurrun 已提交
531
    for (i = 0; i < s->nb_streams; i++) {
532
        st = s->streams[i];
533

534
        ts_st = av_mallocz(sizeof(MpegTSWriteStream));
535 536
        if (!ts_st) {
            ret = AVERROR(ENOMEM);
537
            goto fail;
538
        }
539
        st->priv_data = ts_st;
540 541 542 543

        ts_st->user_tb = st->time_base;
        avpriv_set_pts_info(st, 33, 1, 90000);

544
        ts_st->payload = av_mallocz(ts->pes_payload_size);
545 546
        if (!ts_st->payload) {
            ret = AVERROR(ENOMEM);
547
            goto fail;
548
        }
549
        ts_st->service = service;
550 551 552
        /* MPEG pid values < 16 are reserved. Applications which set st->id in
         * this range are assigned a calculated pid. */
        if (st->id < 16) {
553
            ts_st->pid = ts->start_pid + i;
554 555 556
        } else if (st->id < 0x1FFF) {
            ts_st->pid = st->id;
        } else {
D
Diego Biurrun 已提交
557 558
            av_log(s, AV_LOG_ERROR,
                   "Invalid stream id %d, must be less than 8191\n", st->id);
559
            ret = AVERROR(EINVAL);
560 561 562 563
            goto fail;
        }
        if (ts_st->pid == service->pmt.pid) {
            av_log(s, AV_LOG_ERROR, "Duplicate stream id %d\n", ts_st->pid);
564
            ret = AVERROR(EINVAL);
565 566
            goto fail;
        }
D
Diego Biurrun 已提交
567
        for (j = 0; j < i; j++) {
568 569
            if (pids[j] == ts_st->pid) {
                av_log(s, AV_LOG_ERROR, "Duplicate stream id %d\n", ts_st->pid);
570
                ret = AVERROR(EINVAL);
571 572
                goto fail;
            }
D
Diego Biurrun 已提交
573 574 575 576
        }
        pids[i]                = ts_st->pid;
        ts_st->payload_pts     = AV_NOPTS_VALUE;
        ts_st->payload_dts     = AV_NOPTS_VALUE;
577
        ts_st->first_pts_check = 1;
D
Diego Biurrun 已提交
578
        ts_st->cc              = 15;
579
        /* update PCR pid by using the first video stream */
580
        if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
581
            service->pcr_pid == 0x1fff) {
582
            service->pcr_pid = ts_st->pid;
D
Diego Biurrun 已提交
583
            pcr_st           = st;
584
        }
585
        if (st->codec->codec_id == AV_CODEC_ID_AAC &&
D
Diego Biurrun 已提交
586
            st->codec->extradata_size > 0) {
587 588 589 590
            AVStream *ast;
            ts_st->amux = avformat_alloc_context();
            if (!ts_st->amux) {
                ret = AVERROR(ENOMEM);
591
                goto fail;
592
            }
D
Diego Biurrun 已提交
593 594 595
            ts_st->amux->oformat =
                av_guess_format((ts->flags & MPEGTS_FLAG_AAC_LATM) ? "latm" : "adts",
                                NULL, NULL);
596 597 598 599
            if (!ts_st->amux->oformat) {
                ret = AVERROR(EINVAL);
                goto fail;
            }
600 601 602 603
            if (!(ast = avformat_new_stream(ts_st->amux, NULL))) {
                ret = AVERROR(ENOMEM);
                goto fail;
            }
604 605 606 607 608
            ret = avcodec_copy_context(ast->codec, st->codec);
            if (ret != 0)
                goto fail;
            ret = avformat_write_header(ts_st->amux, NULL);
            if (ret < 0)
609
                goto fail;
610
        }
611
    }
612

613 614
    av_free(pids);

615 616
    /* if no video stream, use the first stream as PCR */
    if (service->pcr_pid == 0x1fff && s->nb_streams > 0) {
D
Diego Biurrun 已提交
617 618
        pcr_st           = s->streams[0];
        ts_st            = pcr_st->priv_data;
619
        service->pcr_pid = ts_st->pid;
620 621
    } else
        ts_st = pcr_st->priv_data;
622

623
    if (ts->mux_rate > 1) {
624
        service->pcr_packet_period = (ts->mux_rate * ts->pcr_period) /
D
Diego Biurrun 已提交
625
                                     (TS_PACKET_SIZE * 8 * 1000);
B
Baptiste Coudurier 已提交
626
        ts->sdt_packet_period      = (ts->mux_rate * SDT_RETRANS_TIME) /
D
Diego Biurrun 已提交
627
                                     (TS_PACKET_SIZE * 8 * 1000);
B
Baptiste Coudurier 已提交
628
        ts->pat_packet_period      = (ts->mux_rate * PAT_RETRANS_TIME) /
D
Diego Biurrun 已提交
629
                                     (TS_PACKET_SIZE * 8 * 1000);
B
Baptiste Coudurier 已提交
630

631
        ts->first_pcr = av_rescale(s->max_delay, PCR_TIME_BASE, AV_TIME_BASE);
632 633 634 635
    } else {
        /* Arbitrary values, PAT/PMT could be written on key frames */
        ts->sdt_packet_period = 200;
        ts->pat_packet_period = 40;
636
        if (pcr_st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
637 638 639
            if (!pcr_st->codec->frame_size) {
                av_log(s, AV_LOG_WARNING, "frame size not set\n");
                service->pcr_packet_period =
D
Diego Biurrun 已提交
640
                    pcr_st->codec->sample_rate / (10 * 512);
641 642
            } else {
                service->pcr_packet_period =
D
Diego Biurrun 已提交
643
                    pcr_st->codec->sample_rate / (10 * pcr_st->codec->frame_size);
644 645 646
            }
        } else {
            // max delta PCR 0.1s
647
            // TODO: should be avg_frame_rate
648
            service->pcr_packet_period =
649
                ts_st->user_tb.den / (10 * ts_st->user_tb.num);
650 651 652
        }
    }

653 654
    // output a PCR as soon as possible
    service->pcr_packet_count = service->pcr_packet_period;
D
Diego Biurrun 已提交
655 656
    ts->pat_packet_count      = ts->pat_packet_period - 1;
    ts->sdt_packet_count      = ts->sdt_packet_period - 1;
657

658
    if (ts->mux_rate == 1)
659
        av_log(s, AV_LOG_VERBOSE, "muxrate VBR, ");
660
    else
661
        av_log(s, AV_LOG_VERBOSE, "muxrate %d, ", ts->mux_rate);
D
Diego Biurrun 已提交
662 663
    av_log(s, AV_LOG_VERBOSE,
           "pcr every %d pkts, sdt every %d, pat/pmt every %d pkts\n",
664
           service->pcr_packet_period,
665
           ts->sdt_packet_period, ts->pat_packet_period);
666

667
    avio_flush(s->pb);
668 669 670

    return 0;

D
Diego Biurrun 已提交
671
fail:
672
    av_free(service);
673
    av_free(pids);
D
Diego Biurrun 已提交
674 675
    for (i = 0; i < s->nb_streams; i++) {
        st    = s->streams[i];
676 677 678
        ts_st = st->priv_data;
        if (ts_st) {
            av_freep(&ts_st->payload);
679 680
            if (ts_st->amux) {
                avformat_free_context(ts_st->amux);
681
                ts_st->amux = NULL;
682
            }
683
        }
684
        av_freep(&st->priv_data);
685
    }
686
    return ret;
687 688 689 690 691 692 693 694
}

/* send SDT, PAT and PMT tables regulary */
static void retransmit_si_info(AVFormatContext *s)
{
    MpegTSWrite *ts = s->priv_data;
    int i;

695
    if (++ts->sdt_packet_count == ts->sdt_packet_period) {
696 697 698
        ts->sdt_packet_count = 0;
        mpegts_write_sdt(s);
    }
699
    if (++ts->pat_packet_count == ts->pat_packet_period) {
700 701
        ts->pat_packet_count = 0;
        mpegts_write_pat(s);
D
Diego Biurrun 已提交
702
        for (i = 0; i < ts->nb_services; i++)
703 704 705 706
            mpegts_write_pmt(s, ts->services[i]);
    }
}

707
static int64_t get_pcr(const MpegTSWrite *ts, AVIOContext *pb)
708
{
709
    return av_rescale(avio_tell(pb) + 11, 8 * PCR_TIME_BASE, ts->mux_rate) +
710 711 712
           ts->first_pcr;
}

713
static int write_pcr_bits(uint8_t *buf, int64_t pcr)
714 715 716 717 718
{
    int64_t pcr_low = pcr % 300, pcr_high = pcr / 300;

    *buf++ = pcr_high >> 25;
    *buf++ = pcr_high >> 17;
D
Diego Biurrun 已提交
719 720 721
    *buf++ = pcr_high >>  9;
    *buf++ = pcr_high >>  1;
    *buf++ = pcr_high <<  7 | pcr_low >> 8 | 0x7e;
722 723
    *buf++ = pcr_low;

724
    return 6;
725 726
}

727 728 729 730 731 732
/* Write a single null transport stream packet */
static void mpegts_insert_null_packet(AVFormatContext *s)
{
    uint8_t *q;
    uint8_t buf[TS_PACKET_SIZE];

D
Diego Biurrun 已提交
733
    q    = buf;
734 735 736 737 738
    *q++ = 0x47;
    *q++ = 0x00 | 0x1f;
    *q++ = 0xff;
    *q++ = 0x10;
    memset(q, 0x0FF, TS_PACKET_SIZE - (q - buf));
739
    avio_write(s->pb, buf, TS_PACKET_SIZE);
740 741 742 743 744 745 746 747 748 749
}

/* Write a single transport stream packet with a PCR and no payload */
static void mpegts_insert_pcr_only(AVFormatContext *s, AVStream *st)
{
    MpegTSWrite *ts = s->priv_data;
    MpegTSWriteStream *ts_st = st->priv_data;
    uint8_t *q;
    uint8_t buf[TS_PACKET_SIZE];

D
Diego Biurrun 已提交
750
    q    = buf;
751 752 753 754 755 756 757 758 759
    *q++ = 0x47;
    *q++ = ts_st->pid >> 8;
    *q++ = ts_st->pid;
    *q++ = 0x20 | ts_st->cc;   /* Adaptation only */
    /* Continuity Count field does not increment (see 13818-1 section 2.4.3.3) */
    *q++ = TS_PACKET_SIZE - 5; /* Adaptation Field Length */
    *q++ = 0x10;               /* Adaptation flags: PCR present */

    /* PCR coded into 6 bytes */
760
    q += write_pcr_bits(q, get_pcr(ts, s->pb));
761 762 763

    /* stuffing bytes */
    memset(q, 0xFF, TS_PACKET_SIZE - (q - buf));
764
    avio_write(s->pb, buf, TS_PACKET_SIZE);
765 766
}

767 768 769 770
static void write_pts(uint8_t *q, int fourbits, int64_t pts)
{
    int val;

D
Diego Biurrun 已提交
771
    val  = fourbits << 4 | (((pts >> 30) & 0x07) << 1) | 1;
772
    *q++ = val;
D
Diego Biurrun 已提交
773
    val  = (((pts >> 15) & 0x7fff) << 1) | 1;
774 775
    *q++ = val >> 8;
    *q++ = val;
D
Diego Biurrun 已提交
776
    val  = (((pts) & 0x7fff) << 1) | 1;
777 778 779 780
    *q++ = val >> 8;
    *q++ = val;
}

781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813
/* Set an adaptation field flag in an MPEG-TS packet*/
static void set_af_flag(uint8_t *pkt, int flag)
{
    // expect at least one flag to set
    assert(flag);

    if ((pkt[3] & 0x20) == 0) {
        // no AF yet, set adaptation field flag
        pkt[3] |= 0x20;
        // 1 byte length, no flags
        pkt[4] = 1;
        pkt[5] = 0;
    }
    pkt[5] |= flag;
}

/* Extend the adaptation field by size bytes */
static void extend_af(uint8_t *pkt, int size)
{
    // expect already existing adaptation field
    assert(pkt[3] & 0x20);
    pkt[4] += size;
}

/* Get a pointer to MPEG-TS payload (right after TS packet header) */
static uint8_t *get_ts_payload_start(uint8_t *pkt)
{
    if (pkt[3] & 0x20)
        return pkt + 5 + pkt[4];
    else
        return pkt + 4;
}

D
Diego Biurrun 已提交
814 815 816 817
/* Add a PES header to the front of the payload, and segment into an integer
 * number of TS packets. The final TS packet is padded using an oversized
 * adaptation header to exactly fill the last TS packet.
 * NOTE: 'payload' contains a complete PES payload. */
818 819
static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
                             const uint8_t *payload, int payload_size,
820
                             int64_t pts, int64_t dts, int key)
821 822
{
    MpegTSWriteStream *ts_st = st->priv_data;
823
    MpegTSWrite *ts = s->priv_data;
824
    uint8_t buf[TS_PACKET_SIZE];
825
    uint8_t *q;
826
    int val, is_start, len, header_len, write_pcr, private_code, flags;
827 828
    int afc_len, stuffing_len;
    int64_t pcr = -1; /* avoid warning */
829
    int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE);
830

831 832 833
    is_start = 1;
    while (payload_size > 0) {
        retransmit_si_info(s);
834

835 836
        write_pcr = 0;
        if (ts_st->pid == ts_st->service->pcr_pid) {
837 838
            if (ts->mux_rate > 1 || is_start) // VBR pcr period is based on frames
                ts_st->service->pcr_packet_count++;
839
            if (ts_st->service->pcr_packet_count >=
840
                ts_st->service->pcr_packet_period) {
841 842 843 844 845
                ts_st->service->pcr_packet_count = 0;
                write_pcr = 1;
            }
        }

846
        if (ts->mux_rate > 1 && dts != AV_NOPTS_VALUE &&
D
Diego Biurrun 已提交
847
            (dts - get_pcr(ts, s->pb) / 300) > delay) {
848 849 850 851 852
            /* pcr insert gets priority over null packet insert */
            if (write_pcr)
                mpegts_insert_pcr_only(s, st);
            else
                mpegts_insert_null_packet(s);
D
Diego Biurrun 已提交
853 854
            /* recalculate write_pcr and possibly retransmit si_info */
            continue;
855 856
        }

857
        /* prepare packet header */
D
Diego Biurrun 已提交
858
        q    = buf;
859
        *q++ = 0x47;
860
        val  = ts_st->pid >> 8;
861 862
        if (is_start)
            val |= 0x40;
D
Diego Biurrun 已提交
863 864
        *q++      = val;
        *q++      = ts_st->pid;
865
        ts_st->cc = ts_st->cc + 1 & 0xf;
D
Diego Biurrun 已提交
866
        *q++      = 0x10 | ts_st->cc; // payload indicator + CC
867 868 869 870 871 872 873
        if (key && is_start && pts != AV_NOPTS_VALUE) {
            // set Random Access for key frames
            if (ts_st->pid == ts_st->service->pcr_pid)
                write_pcr = 1;
            set_af_flag(buf, 0x40);
            q = get_ts_payload_start(buf);
        }
874
        if (write_pcr) {
875 876
            set_af_flag(buf, 0x10);
            q = get_ts_payload_start(buf);
877
            // add 11, pcr references the last byte of program clock reference base
878
            if (ts->mux_rate > 1)
879
                pcr = get_pcr(ts, s->pb);
880
            else
D
Diego Biurrun 已提交
881
                pcr = (dts - delay) * 300;
882
            if (dts != AV_NOPTS_VALUE && dts < pcr / 300)
883
                av_log(s, AV_LOG_WARNING, "dts < pcr, TS is invalid\n");
884 885
            extend_af(buf, write_pcr_bits(q, pcr));
            q = get_ts_payload_start(buf);
886
        }
887
        if (is_start) {
888
            int pes_extension = 0;
889 890 891 892
            /* write PES header */
            *q++ = 0x00;
            *q++ = 0x00;
            *q++ = 0x01;
893
            private_code = 0;
894
            if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
D
Diego Biurrun 已提交
895
                if (st->codec->codec_id == AV_CODEC_ID_DIRAC)
896
                    *q++ = 0xfd;
D
Diego Biurrun 已提交
897
                else
898
                    *q++ = 0xe0;
899
            } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
900 901 902
                       (st->codec->codec_id == AV_CODEC_ID_MP2 ||
                        st->codec->codec_id == AV_CODEC_ID_MP3 ||
                        st->codec->codec_id == AV_CODEC_ID_AAC)) {
903
                *q++ = 0xc0;
904 905
            } else {
                *q++ = 0xbd;
D
Diego Biurrun 已提交
906
                if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE)
907 908
                    private_code = 0x20;
            }
909
            header_len = 0;
D
Diego Biurrun 已提交
910
            flags      = 0;
911 912
            if (pts != AV_NOPTS_VALUE) {
                header_len += 5;
D
Diego Biurrun 已提交
913
                flags      |= 0x80;
914
            }
915
            if (dts != AV_NOPTS_VALUE && pts != AV_NOPTS_VALUE && dts != pts) {
916
                header_len += 5;
D
Diego Biurrun 已提交
917
                flags      |= 0x40;
918
            }
919
            if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
920
                st->codec->codec_id == AV_CODEC_ID_DIRAC) {
921 922
                /* set PES_extension_flag */
                pes_extension = 1;
D
Diego Biurrun 已提交
923
                flags        |= 0x01;
924

D
Diego Biurrun 已提交
925 926 927
                /* One byte for PES2 extension flag +
                 * one byte for extension length +
                 * one byte for extension id */
928 929
                header_len += 3;
            }
930
            len = payload_size + header_len + 3;
931
            if (private_code != 0)
932
                len++;
933 934
            if (len > 0xffff)
                len = 0;
935 936
            *q++ = len >> 8;
            *q++ = len;
D
Diego Biurrun 已提交
937
            val  = 0x80;
938
            /* data alignment indicator is required for subtitle data */
939
            if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE)
940 941
                val |= 0x04;
            *q++ = val;
942 943
            *q++ = flags;
            *q++ = header_len;
944
            if (pts != AV_NOPTS_VALUE) {
945 946 947
                write_pts(q, flags >> 6, pts);
                q += 5;
            }
948
            if (dts != AV_NOPTS_VALUE && pts != AV_NOPTS_VALUE && dts != pts) {
949 950
                write_pts(q, 1, dts);
                q += 5;
951
            }
952
            if (pes_extension && st->codec->codec_id == AV_CODEC_ID_DIRAC) {
953
                flags = 0x01;  /* set PES_extension_flag_2 */
D
Diego Biurrun 已提交
954 955 956 957
                *q++  = flags;
                *q++  = 0x80 | 0x01; /* marker bit + extension length */
                /* Set the stream ID extension flag bit to 0 and
                 * write the extended stream ID. */
958 959
                *q++ = 0x00 | 0x60;
            }
960 961
            if (private_code != 0)
                *q++ = private_code;
962
            is_start = 0;
963
        }
964 965 966 967
        /* header size */
        header_len = q - buf;
        /* data len */
        len = TS_PACKET_SIZE - header_len;
968 969
        if (len > payload_size)
            len = payload_size;
970 971 972 973 974 975 976
        stuffing_len = TS_PACKET_SIZE - header_len - len;
        if (stuffing_len > 0) {
            /* add stuffing with AFC */
            if (buf[3] & 0x20) {
                /* stuffing already present: increase its size */
                afc_len = buf[4] + 1;
                memmove(buf + 4 + afc_len + stuffing_len,
977
                        buf + 4 + afc_len,
978 979 980 981 982 983 984
                        header_len - (4 + afc_len));
                buf[4] += stuffing_len;
                memset(buf + 4 + afc_len, 0xff, stuffing_len);
            } else {
                /* add stuffing */
                memmove(buf + 4 + stuffing_len, buf + 4, header_len - 4);
                buf[3] |= 0x20;
D
Diego Biurrun 已提交
985
                buf[4]  = stuffing_len - 1;
986 987 988 989 990 991 992
                if (stuffing_len >= 2) {
                    buf[5] = 0x00;
                    memset(buf + 6, 0xff, stuffing_len - 2);
                }
            }
        }
        memcpy(buf + TS_PACKET_SIZE - len, payload, len);
D
Diego Biurrun 已提交
993
        payload      += len;
994
        payload_size -= len;
995
        avio_write(s->pb, buf, TS_PACKET_SIZE);
996
    }
997
    avio_flush(s->pb);
998 999
}

1000
static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
1001
{
1002
    AVStream *st = s->streams[pkt->stream_index];
1003
    int size = pkt->size;
D
Diego Biurrun 已提交
1004 1005
    uint8_t *buf = pkt->data;
    uint8_t *data = NULL;
1006
    MpegTSWrite *ts = s->priv_data;
1007
    MpegTSWriteStream *ts_st = st->priv_data;
D
Diego Biurrun 已提交
1008
    const uint64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE) * 2;
1009 1010
    int64_t dts = AV_NOPTS_VALUE, pts = AV_NOPTS_VALUE;

1011
    if (ts->reemit_pat_pmt) {
D
Diego Biurrun 已提交
1012 1013
        av_log(s, AV_LOG_WARNING,
               "resend_headers option is deprecated, use -mpegts_flags resend_headers\n");
1014
        ts->reemit_pat_pmt = 0;
D
Diego Biurrun 已提交
1015
        ts->flags         |= MPEGTS_FLAG_REEMIT_PAT_PMT;
1016 1017 1018
    }

    if (ts->flags & MPEGTS_FLAG_REEMIT_PAT_PMT) {
1019 1020
        ts->pat_packet_count = ts->pat_packet_period - 1;
        ts->sdt_packet_count = ts->sdt_packet_period - 1;
D
Diego Biurrun 已提交
1021
        ts->flags           &= ~MPEGTS_FLAG_REEMIT_PAT_PMT;
1022 1023
    }

1024 1025 1026 1027
    if (pkt->pts != AV_NOPTS_VALUE)
        pts = pkt->pts + delay;
    if (pkt->dts != AV_NOPTS_VALUE)
        dts = pkt->dts + delay;
1028

1029 1030
    if (ts_st->first_pts_check && pts == AV_NOPTS_VALUE) {
        av_log(s, AV_LOG_ERROR, "first pts value must set\n");
1031
        return AVERROR_INVALIDDATA;
1032 1033 1034
    }
    ts_st->first_pts_check = 0;

1035
    if (st->codec->codec_id == AV_CODEC_ID_H264) {
D
Diego Biurrun 已提交
1036
        const uint8_t *p = buf, *buf_end = p + size;
1037 1038
        uint32_t state = -1;

1039
        if (pkt->size < 5 || AV_RB32(pkt->data) != 0x0000001) {
D
Diego Biurrun 已提交
1040
            av_log(s, AV_LOG_ERROR, "H.264 bitstream malformed, "
M
Mike Melanson 已提交
1041
                   "no startcode found, use -bsf h264_mp4toannexb\n");
1042
            return AVERROR_INVALIDDATA;
1043
        }
1044 1045

        do {
1046
            p = avpriv_find_start_code(p, buf_end, &state);
1047
            av_dlog(s, "nal %d\n", state & 0x1f);
1048 1049 1050 1051
        } while (p < buf_end && (state & 0x1f) != 9 &&
                 (state & 0x1f) != 5 && (state & 0x1f) != 1);

        if ((state & 0x1f) != 9) { // AUD NAL
D
Diego Biurrun 已提交
1052
            data = av_malloc(pkt->size + 6);
1053
            if (!data)
1054
                return AVERROR(ENOMEM);
D
Diego Biurrun 已提交
1055
            memcpy(data + 6, pkt->data, pkt->size);
1056 1057
            AV_WB32(data, 0x00000001);
            data[4] = 0x09;
1058
            data[5] = 0xf0; // any slice type (0xe) + rbsp stop one bit
D
Diego Biurrun 已提交
1059 1060
            buf     = data;
            size    = pkt->size + 6;
1061
        }
1062
    } else if (st->codec->codec_id == AV_CODEC_ID_AAC) {
1063 1064
        if (pkt->size < 2) {
            av_log(s, AV_LOG_ERROR, "AAC packet too short\n");
1065
            return AVERROR_INVALIDDATA;
1066
        }
1067
        if ((AV_RB16(pkt->data) & 0xfff0) != 0xfff0) {
1068 1069 1070 1071 1072
            int ret;
            AVPacket pkt2;

            if (!ts_st->amux) {
                av_log(s, AV_LOG_ERROR, "AAC bitstream not in ADTS format "
D
Diego Biurrun 已提交
1073
                                        "and extradata missing\n");
1074
                return AVERROR_INVALIDDATA;
1075
            }
1076 1077 1078 1079

            av_init_packet(&pkt2);
            pkt2.data = pkt->data;
            pkt2.size = pkt->size;
D
Diego Biurrun 已提交
1080

1081 1082
            ret = avio_open_dyn_buf(&ts_st->amux->pb);
            if (ret < 0)
1083
                return AVERROR(ENOMEM);
1084 1085 1086

            ret = av_write_frame(ts_st->amux, &pkt2);
            if (ret < 0) {
1087 1088
                avio_close_dyn_buf(ts_st->amux->pb, &data);
                ts_st->amux->pb = NULL;
A
Alex Converse 已提交
1089
                av_free(data);
1090
                return ret;
A
Alex Converse 已提交
1091
            }
D
Diego Biurrun 已提交
1092
            size            = avio_close_dyn_buf(ts_st->amux->pb, &data);
1093
            ts_st->amux->pb = NULL;
D
Diego Biurrun 已提交
1094
            buf             = data;
1095
        }
1096 1097
    }

1098
    if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO) {
1099
        // for video and subtitle, write a single pes packet
D
Diego Biurrun 已提交
1100 1101
        mpegts_write_pes(s, st, buf, size, pts, dts,
                         pkt->flags & AV_PKT_FLAG_KEY);
1102
        av_free(data);
1103 1104 1105
        return 0;
    }

1106
    if (ts_st->payload_size + size > ts->pes_payload_size) {
1107 1108 1109 1110 1111 1112
        if (ts_st->payload_size) {
            mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_size,
                             ts_st->payload_pts, ts_st->payload_dts,
                             ts_st->payload_flags & AV_PKT_FLAG_KEY);
            ts_st->payload_size = 0;
        }
1113
        if (size > ts->pes_payload_size) {
1114 1115 1116 1117 1118
            mpegts_write_pes(s, st, buf, size, pts, dts,
                             pkt->flags & AV_PKT_FLAG_KEY);
            av_free(data);
            return 0;
        }
1119 1120
    }

1121
    if (!ts_st->payload_size) {
D
Diego Biurrun 已提交
1122 1123
        ts_st->payload_pts   = pts;
        ts_st->payload_dts   = dts;
1124
        ts_st->payload_flags = pkt->flags;
1125
    }
1126

1127 1128
    memcpy(ts_st->payload + ts_st->payload_size, buf, size);
    ts_st->payload_size += size;
1129

1130 1131
    av_free(data);

1132 1133 1134
    return 0;
}

1135
static void mpegts_write_flush(AVFormatContext *s)
1136 1137 1138 1139
{
    int i;

    /* flush current packets */
D
Diego Biurrun 已提交
1140
    for (i = 0; i < s->nb_streams; i++) {
1141 1142
        AVStream *st = s->streams[i];
        MpegTSWriteStream *ts_st = st->priv_data;
1143 1144
        if (ts_st->payload_size > 0) {
            mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_size,
1145 1146
                             ts_st->payload_pts, ts_st->payload_dts,
                             ts_st->payload_flags & AV_PKT_FLAG_KEY);
1147
            ts_st->payload_size = 0;
1148
        }
1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170
    }
    avio_flush(s->pb);
}

static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt)
{
    if (!pkt) {
        mpegts_write_flush(s);
        return 1;
    } else {
        return mpegts_write_packet_internal(s, pkt);
    }
}

static int mpegts_write_end(AVFormatContext *s)
{
    MpegTSWrite *ts = s->priv_data;
    MpegTSService *service;
    int i;

    mpegts_write_flush(s);

D
Diego Biurrun 已提交
1171
    for (i = 0; i < s->nb_streams; i++) {
1172 1173
        AVStream *st = s->streams[i];
        MpegTSWriteStream *ts_st = st->priv_data;
1174
        av_freep(&ts_st->payload);
1175 1176
        if (ts_st->amux) {
            avformat_free_context(ts_st->amux);
1177
            ts_st->amux = NULL;
1178
        }
1179
    }
1180

D
Diego Biurrun 已提交
1181
    for (i = 0; i < ts->nb_services; i++) {
1182 1183 1184 1185 1186 1187 1188 1189 1190 1191
        service = ts->services[i];
        av_freep(&service->provider_name);
        av_freep(&service->name);
        av_free(service);
    }
    av_free(ts->services);

    return 0;
}

1192 1193
static const AVOption options[] = {
    { "mpegts_transport_stream_id", "Set transport_stream_id field.",
D
Diego Biurrun 已提交
1194 1195
      offsetof(MpegTSWrite, transport_stream_id), AV_OPT_TYPE_INT,
      { .i64 = 0x0001 }, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM },
1196
    { "mpegts_original_network_id", "Set original_network_id field.",
D
Diego Biurrun 已提交
1197 1198
      offsetof(MpegTSWrite, original_network_id), AV_OPT_TYPE_INT,
      { .i64 = 0x0001 }, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM },
1199
    { "mpegts_service_id", "Set service_id field.",
D
Diego Biurrun 已提交
1200 1201
      offsetof(MpegTSWrite, service_id), AV_OPT_TYPE_INT,
      { .i64 = 0x0001 }, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM },
1202
    { "mpegts_pmt_start_pid", "Set the first pid of the PMT.",
D
Diego Biurrun 已提交
1203 1204
      offsetof(MpegTSWrite, pmt_start_pid), AV_OPT_TYPE_INT,
      { .i64 = 0x1000 }, 0x1000, 0x1f00, AV_OPT_FLAG_ENCODING_PARAM },
1205
    { "mpegts_start_pid", "Set the first pid.",
D
Diego Biurrun 已提交
1206 1207 1208 1209 1210
      offsetof(MpegTSWrite, start_pid), AV_OPT_TYPE_INT,
      { .i64 = 0x0100 }, 0x0100, 0x0f00, AV_OPT_FLAG_ENCODING_PARAM },
    { "muxrate", NULL,
      offsetof(MpegTSWrite, mux_rate), AV_OPT_TYPE_INT,
      { .i64 = 1 }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
1211
    { "pes_payload_size", "Minimum PES packet payload in bytes",
D
Diego Biurrun 已提交
1212 1213 1214 1215
      offsetof(MpegTSWrite, pes_payload_size), AV_OPT_TYPE_INT,
      { .i64 = DEFAULT_PES_PAYLOAD_SIZE }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
    { "mpegts_flags", "MPEG-TS muxing flags",
      offsetof(MpegTSWrite, flags), AV_OPT_TYPE_FLAGS, { .i64 = 0 }, 0, INT_MAX,
1216 1217
      AV_OPT_FLAG_ENCODING_PARAM, "mpegts_flags" },
    { "resend_headers", "Reemit PAT/PMT before writing the next packet",
D
Diego Biurrun 已提交
1218 1219
      0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_FLAG_REEMIT_PAT_PMT }, 0, INT_MAX,
      AV_OPT_FLAG_ENCODING_PARAM, "mpegts_flags" },
1220
    { "latm", "Use LATM packetization for AAC",
D
Diego Biurrun 已提交
1221 1222
      0, AV_OPT_TYPE_CONST, { .i64 = MPEGTS_FLAG_AAC_LATM }, 0, INT_MAX,
      AV_OPT_FLAG_ENCODING_PARAM, "mpegts_flags" },
1223 1224
    // backward compatibility
    { "resend_headers", "Reemit PAT/PMT before writing the next packet",
D
Diego Biurrun 已提交
1225 1226
      offsetof(MpegTSWrite, reemit_pat_pmt), AV_OPT_TYPE_INT,
      { .i64 = 0 }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
1227
    { "pcr_period", "PCR retransmission time",
D
Diego Biurrun 已提交
1228 1229
      offsetof(MpegTSWrite, pcr_period), AV_OPT_TYPE_INT,
      { .i64 = PCR_RETRANS_TIME }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
1230 1231 1232 1233
    { NULL },
};

static const AVClass mpegts_muxer_class = {
D
Diego Biurrun 已提交
1234 1235 1236 1237
    .class_name = "MPEGTS muxer",
    .item_name  = av_default_item_name,
    .option     = options,
    .version    = LIBAVUTIL_VERSION_INT,
1238 1239
};

1240
AVOutputFormat ff_mpegts_muxer = {
D
Diego Biurrun 已提交
1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252
    .name           = "mpegts",
    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-TS (MPEG-2 Transport Stream)"),
    .mime_type      = "video/x-mpegts",
    .extensions     = "ts,m2t",
    .priv_data_size = sizeof(MpegTSWrite),
    .audio_codec    = AV_CODEC_ID_MP2,
    .video_codec    = AV_CODEC_ID_MPEG2VIDEO,
    .write_header   = mpegts_write_header,
    .write_packet   = mpegts_write_packet,
    .write_trailer  = mpegts_write_end,
    .flags          = AVFMT_ALLOW_FLUSH,
    .priv_class     = &mpegts_muxer_class,
1253
};