~ubuntu-branches/ubuntu/saucy/gst-libav1.0/saucy-proposed

« back to all changes in this revision

Viewing changes to gst-libs/ext/libav/libavformat/mpegtsenc.c

  • Committer: Package Import Robot
  • Author(s): Sebastian Dröge
  • Date: 2013-07-30 09:00:15 UTC
  • mfrom: (1.1.16) (7.1.7 experimental)
  • Revision ID: package-import@ubuntu.com-20130730090015-sc1ou2yssu7q5w4e
Tags: 1.1.3-1
* New upstream development snapshot:
  + debian/control:
    - Build depend on GStreamer and gst-plugins-base >= 1.1.3.

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
#include "avformat.h"
29
29
#include "internal.h"
30
30
#include "mpegts.h"
31
 
#include "adts.h"
32
31
 
33
32
#define PCR_TIME_BASE 27000000
34
33
 
76
75
 
77
76
    int pmt_start_pid;
78
77
    int start_pid;
 
78
 
 
79
    int reemit_pat_pmt; // backward compatibility
 
80
 
 
81
#define MPEGTS_FLAG_REEMIT_PAT_PMT  0x01
 
82
#define MPEGTS_FLAG_AAC_LATM        0x02
 
83
    int flags;
79
84
} MpegTSWrite;
80
85
 
81
86
/* a PES packet header is generated every DEFAULT_PES_HEADER_FREQ packets */
84
89
 
85
90
static const AVOption options[] = {
86
91
    { "mpegts_transport_stream_id", "Set transport_stream_id field.",
87
 
      offsetof(MpegTSWrite, transport_stream_id), AV_OPT_TYPE_INT, {.dbl = 0x0001 }, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM},
 
92
      offsetof(MpegTSWrite, transport_stream_id), AV_OPT_TYPE_INT, {.i64 = 0x0001 }, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM},
88
93
    { "mpegts_original_network_id", "Set original_network_id field.",
89
 
      offsetof(MpegTSWrite, original_network_id), AV_OPT_TYPE_INT, {.dbl = 0x0001 }, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM},
 
94
      offsetof(MpegTSWrite, original_network_id), AV_OPT_TYPE_INT, {.i64 = 0x0001 }, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM},
90
95
    { "mpegts_service_id", "Set service_id field.",
91
 
      offsetof(MpegTSWrite, service_id), AV_OPT_TYPE_INT, {.dbl = 0x0001 }, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM},
 
96
      offsetof(MpegTSWrite, service_id), AV_OPT_TYPE_INT, {.i64 = 0x0001 }, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM},
92
97
    { "mpegts_pmt_start_pid", "Set the first pid of the PMT.",
93
 
      offsetof(MpegTSWrite, pmt_start_pid), AV_OPT_TYPE_INT, {.dbl = 0x1000 }, 0x1000, 0x1f00, AV_OPT_FLAG_ENCODING_PARAM},
 
98
      offsetof(MpegTSWrite, pmt_start_pid), AV_OPT_TYPE_INT, {.i64 = 0x1000 }, 0x1000, 0x1f00, AV_OPT_FLAG_ENCODING_PARAM},
94
99
    { "mpegts_start_pid", "Set the first pid.",
95
 
      offsetof(MpegTSWrite, start_pid), AV_OPT_TYPE_INT, {.dbl = 0x0100 }, 0x0100, 0x0f00, AV_OPT_FLAG_ENCODING_PARAM},
96
 
    { "muxrate", NULL, offsetof(MpegTSWrite, mux_rate), AV_OPT_TYPE_INT, {1}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
 
100
      offsetof(MpegTSWrite, start_pid), AV_OPT_TYPE_INT, {.i64 = 0x0100 }, 0x0100, 0x0f00, AV_OPT_FLAG_ENCODING_PARAM},
 
101
    { "muxrate", NULL, offsetof(MpegTSWrite, mux_rate), AV_OPT_TYPE_INT, {.i64 = 1}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
97
102
    { "pes_payload_size", "Minimum PES packet payload in bytes",
98
 
      offsetof(MpegTSWrite, pes_payload_size), AV_OPT_TYPE_INT, {DEFAULT_PES_PAYLOAD_SIZE}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
 
103
      offsetof(MpegTSWrite, pes_payload_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT_PES_PAYLOAD_SIZE}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
 
104
    { "mpegts_flags", "MPEG-TS muxing flags", offsetof(MpegTSWrite, flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, INT_MAX,
 
105
      AV_OPT_FLAG_ENCODING_PARAM, "mpegts_flags" },
 
106
    { "resend_headers", "Reemit PAT/PMT before writing the next packet",
 
107
      0, AV_OPT_TYPE_CONST, {.i64 = MPEGTS_FLAG_REEMIT_PAT_PMT}, 0, INT_MAX,
 
108
      AV_OPT_FLAG_ENCODING_PARAM, "mpegts_flags"},
 
109
    { "latm", "Use LATM packetization for AAC",
 
110
      0, AV_OPT_TYPE_CONST, {.i64 = MPEGTS_FLAG_AAC_LATM}, 0, INT_MAX,
 
111
      AV_OPT_FLAG_ENCODING_PARAM, "mpegts_flags"},
 
112
    // backward compatibility
 
113
    { "resend_headers", "Reemit PAT/PMT before writing the next packet",
 
114
      offsetof(MpegTSWrite, reemit_pat_pmt), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
99
115
    { NULL },
100
116
};
101
117
 
210
226
    int64_t payload_dts;
211
227
    int payload_flags;
212
228
    uint8_t *payload;
213
 
    ADTSContext *adts;
 
229
    AVFormatContext *amux;
214
230
} MpegTSWriteStream;
215
231
 
216
232
static void mpegts_write_pat(AVFormatContext *s)
232
248
 
233
249
static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
234
250
{
235
 
    //    MpegTSWrite *ts = s->priv_data;
 
251
    MpegTSWrite *ts = s->priv_data;
236
252
    uint8_t data[1012], *q, *desc_length_ptr, *program_info_length_ptr;
237
253
    int val, stream_type, i;
238
254
 
253
269
        MpegTSWriteStream *ts_st = st->priv_data;
254
270
        AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
255
271
        switch(st->codec->codec_id) {
256
 
        case CODEC_ID_MPEG1VIDEO:
257
 
        case CODEC_ID_MPEG2VIDEO:
 
272
        case AV_CODEC_ID_MPEG1VIDEO:
 
273
        case AV_CODEC_ID_MPEG2VIDEO:
258
274
            stream_type = STREAM_TYPE_VIDEO_MPEG2;
259
275
            break;
260
 
        case CODEC_ID_MPEG4:
 
276
        case AV_CODEC_ID_MPEG4:
261
277
            stream_type = STREAM_TYPE_VIDEO_MPEG4;
262
278
            break;
263
 
        case CODEC_ID_H264:
 
279
        case AV_CODEC_ID_H264:
264
280
            stream_type = STREAM_TYPE_VIDEO_H264;
265
281
            break;
266
 
        case CODEC_ID_DIRAC:
 
282
        case AV_CODEC_ID_DIRAC:
267
283
            stream_type = STREAM_TYPE_VIDEO_DIRAC;
268
284
            break;
269
 
        case CODEC_ID_MP2:
270
 
        case CODEC_ID_MP3:
 
285
        case AV_CODEC_ID_MP2:
 
286
        case AV_CODEC_ID_MP3:
271
287
            stream_type = STREAM_TYPE_AUDIO_MPEG1;
272
288
            break;
273
 
        case CODEC_ID_AAC:
274
 
            stream_type = STREAM_TYPE_AUDIO_AAC;
 
289
        case AV_CODEC_ID_AAC:
 
290
            stream_type = (ts->flags & MPEGTS_FLAG_AAC_LATM) ? STREAM_TYPE_AUDIO_AAC_LATM : STREAM_TYPE_AUDIO_AAC;
275
291
            break;
276
 
        case CODEC_ID_AAC_LATM:
 
292
        case AV_CODEC_ID_AAC_LATM:
277
293
            stream_type = STREAM_TYPE_AUDIO_AAC_LATM;
278
294
            break;
279
 
        case CODEC_ID_AC3:
 
295
        case AV_CODEC_ID_AC3:
280
296
            stream_type = STREAM_TYPE_AUDIO_AC3;
281
297
            break;
282
298
        default:
455
471
    const char *service_name;
456
472
    const char *provider_name;
457
473
    int *pids;
 
474
    int ret;
 
475
 
 
476
    if (s->max_delay < 0) /* Not set by the caller */
 
477
        s->max_delay = 0;
458
478
 
459
479
    // round up to a whole number of TS packets
460
480
    ts->pes_payload_size = (ts->pes_payload_size + 14 + 183) / 184 * 184 - 14;
492
512
        st = s->streams[i];
493
513
        avpriv_set_pts_info(st, 33, 1, 90000);
494
514
        ts_st = av_mallocz(sizeof(MpegTSWriteStream));
495
 
        if (!ts_st)
 
515
        if (!ts_st) {
 
516
            ret = AVERROR(ENOMEM);
496
517
            goto fail;
 
518
        }
497
519
        st->priv_data = ts_st;
498
520
        ts_st->payload = av_mallocz(ts->pes_payload_size);
499
 
        if (!ts_st->payload)
 
521
        if (!ts_st->payload) {
 
522
            ret = AVERROR(ENOMEM);
500
523
            goto fail;
 
524
        }
501
525
        ts_st->service = service;
502
526
        /* MPEG pid values < 16 are reserved. Applications which set st->id in
503
527
         * this range are assigned a calculated pid. */
507
531
            ts_st->pid = st->id;
508
532
        } else {
509
533
            av_log(s, AV_LOG_ERROR, "Invalid stream id %d, must be less than 8191\n", st->id);
 
534
            ret = AVERROR(EINVAL);
510
535
            goto fail;
511
536
        }
512
537
        if (ts_st->pid == service->pmt.pid) {
513
538
            av_log(s, AV_LOG_ERROR, "Duplicate stream id %d\n", ts_st->pid);
 
539
            ret = AVERROR(EINVAL);
514
540
            goto fail;
515
541
        }
516
542
        for (j = 0; j < i; j++)
517
543
            if (pids[j] == ts_st->pid) {
518
544
                av_log(s, AV_LOG_ERROR, "Duplicate stream id %d\n", ts_st->pid);
 
545
                ret = AVERROR(EINVAL);
519
546
                goto fail;
520
547
            }
521
548
        pids[i] = ts_st->pid;
529
556
            service->pcr_pid = ts_st->pid;
530
557
            pcr_st = st;
531
558
        }
532
 
        if (st->codec->codec_id == CODEC_ID_AAC &&
533
 
            st->codec->extradata_size > 0) {
534
 
            ts_st->adts = av_mallocz(sizeof(*ts_st->adts));
535
 
            if (!ts_st->adts)
536
 
                goto fail;
537
 
            if (ff_adts_decode_extradata(s, ts_st->adts, st->codec->extradata,
538
 
                                         st->codec->extradata_size) < 0)
 
559
        if (st->codec->codec_id == AV_CODEC_ID_AAC &&
 
560
            st->codec->extradata_size > 0)
 
561
        {
 
562
            AVStream *ast;
 
563
            ts_st->amux = avformat_alloc_context();
 
564
            if (!ts_st->amux) {
 
565
                ret = AVERROR(ENOMEM);
 
566
                goto fail;
 
567
            }
 
568
            ts_st->amux->oformat = av_guess_format((ts->flags & MPEGTS_FLAG_AAC_LATM) ? "latm" : "adts", NULL, NULL);
 
569
            if (!ts_st->amux->oformat) {
 
570
                ret = AVERROR(EINVAL);
 
571
                goto fail;
 
572
            }
 
573
            ast = avformat_new_stream(ts_st->amux, NULL);
 
574
            ret = avcodec_copy_context(ast->codec, st->codec);
 
575
            if (ret != 0)
 
576
                goto fail;
 
577
            ret = avformat_write_header(ts_st->amux, NULL);
 
578
            if (ret < 0)
539
579
                goto fail;
540
580
        }
541
581
    }
549
589
        service->pcr_pid = ts_st->pid;
550
590
    }
551
591
 
552
 
#if FF_API_MUXRATE
553
 
    if (s->mux_rate)
554
 
        ts->mux_rate = s->mux_rate;
555
 
#endif
556
 
 
557
592
    if (ts->mux_rate > 1) {
558
593
        service->pcr_packet_period = (ts->mux_rate * PCR_RETRANS_TIME) /
559
594
            (TS_PACKET_SIZE * 8 * 1000);
589
624
    ts->sdt_packet_count = ts->sdt_packet_period-1;
590
625
 
591
626
    if (ts->mux_rate == 1)
592
 
        av_log(s, AV_LOG_INFO, "muxrate VBR, ");
 
627
        av_log(s, AV_LOG_VERBOSE, "muxrate VBR, ");
593
628
    else
594
 
        av_log(s, AV_LOG_INFO, "muxrate %d, ", ts->mux_rate);
595
 
    av_log(s, AV_LOG_INFO, "pcr every %d pkts, "
 
629
        av_log(s, AV_LOG_VERBOSE, "muxrate %d, ", ts->mux_rate);
 
630
    av_log(s, AV_LOG_VERBOSE, "pcr every %d pkts, "
596
631
           "sdt every %d, pat/pmt every %d pkts\n",
597
632
           service->pcr_packet_period,
598
633
           ts->sdt_packet_period, ts->pat_packet_period);
609
644
        ts_st = st->priv_data;
610
645
        if (ts_st) {
611
646
            av_freep(&ts_st->payload);
612
 
            av_freep(&ts_st->adts);
 
647
            if (ts_st->amux) {
 
648
                avformat_free_context(ts_st->amux);
 
649
                ts_st->amux = NULL;
 
650
            }
613
651
        }
614
652
        av_freep(&st->priv_data);
615
653
    }
616
 
    return -1;
 
654
    return ret;
617
655
}
618
656
 
619
657
/* send SDT, PAT and PMT tables regulary */
823
861
            *q++ = 0x01;
824
862
            private_code = 0;
825
863
            if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
826
 
                if (st->codec->codec_id == CODEC_ID_DIRAC) {
 
864
                if (st->codec->codec_id == AV_CODEC_ID_DIRAC) {
827
865
                    *q++ = 0xfd;
828
866
                } else
829
867
                    *q++ = 0xe0;
830
868
            } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
831
 
                       (st->codec->codec_id == CODEC_ID_MP2 ||
832
 
                        st->codec->codec_id == CODEC_ID_MP3 ||
833
 
                        st->codec->codec_id == CODEC_ID_AAC)) {
 
869
                       (st->codec->codec_id == AV_CODEC_ID_MP2 ||
 
870
                        st->codec->codec_id == AV_CODEC_ID_MP3 ||
 
871
                        st->codec->codec_id == AV_CODEC_ID_AAC)) {
834
872
                *q++ = 0xc0;
835
873
            } else {
836
874
                *q++ = 0xbd;
849
887
                flags |= 0x40;
850
888
            }
851
889
            if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
852
 
                st->codec->codec_id == CODEC_ID_DIRAC) {
 
890
                st->codec->codec_id == AV_CODEC_ID_DIRAC) {
853
891
                /* set PES_extension_flag */
854
892
                pes_extension = 1;
855
893
                flags |= 0x01;
883
921
                write_pts(q, 1, dts);
884
922
                q += 5;
885
923
            }
886
 
            if (pes_extension && st->codec->codec_id == CODEC_ID_DIRAC) {
 
924
            if (pes_extension && st->codec->codec_id == AV_CODEC_ID_DIRAC) {
887
925
                flags = 0x01;  /* set PES_extension_flag_2 */
888
926
                *q++ = flags;
889
927
                *q++ = 0x80 | 0x01;  /* marker bit + extension length */
933
971
    avio_flush(s->pb);
934
972
}
935
973
 
936
 
static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt)
 
974
static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
937
975
{
938
976
    AVStream *st = s->streams[pkt->stream_index];
939
977
    int size = pkt->size;
944
982
    const uint64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE)*2;
945
983
    int64_t dts = AV_NOPTS_VALUE, pts = AV_NOPTS_VALUE;
946
984
 
 
985
    if (ts->reemit_pat_pmt) {
 
986
        av_log(s, AV_LOG_WARNING, "resend_headers option is deprecated, use -mpegts_flags resend_headers\n");
 
987
        ts->reemit_pat_pmt = 0;
 
988
        ts->flags |= MPEGTS_FLAG_REEMIT_PAT_PMT;
 
989
    }
 
990
 
 
991
    if (ts->flags & MPEGTS_FLAG_REEMIT_PAT_PMT) {
 
992
        ts->pat_packet_count = ts->pat_packet_period - 1;
 
993
        ts->sdt_packet_count = ts->sdt_packet_period - 1;
 
994
        ts->flags &= ~MPEGTS_FLAG_REEMIT_PAT_PMT;
 
995
    }
 
996
 
947
997
    if (pkt->pts != AV_NOPTS_VALUE)
948
998
        pts = pkt->pts + delay;
949
999
    if (pkt->dts != AV_NOPTS_VALUE)
951
1001
 
952
1002
    if (ts_st->first_pts_check && pts == AV_NOPTS_VALUE) {
953
1003
        av_log(s, AV_LOG_ERROR, "first pts value must set\n");
954
 
        return -1;
 
1004
        return AVERROR(EINVAL);
955
1005
    }
956
1006
    ts_st->first_pts_check = 0;
957
1007
 
958
 
    if (st->codec->codec_id == CODEC_ID_H264) {
 
1008
    if (st->codec->codec_id == AV_CODEC_ID_H264) {
959
1009
        const uint8_t *p = buf, *buf_end = p+size;
960
1010
        uint32_t state = -1;
961
1011
 
962
1012
        if (pkt->size < 5 || AV_RB32(pkt->data) != 0x0000001) {
963
1013
            av_log(s, AV_LOG_ERROR, "H.264 bitstream malformed, "
964
 
                   "no startcode found, use -vbsf h264_mp4toannexb\n");
965
 
            return -1;
 
1014
                   "no startcode found, use -bsf h264_mp4toannexb\n");
 
1015
            return AVERROR(EINVAL);
966
1016
        }
967
1017
 
968
1018
        do {
969
1019
            p = avpriv_mpv_find_start_code(p, buf_end, &state);
970
 
            //av_log(s, AV_LOG_INFO, "nal %d\n", state & 0x1f);
 
1020
            av_dlog(s, "nal %d\n", state & 0x1f);
971
1021
        } while (p < buf_end && (state & 0x1f) != 9 &&
972
1022
                 (state & 0x1f) != 5 && (state & 0x1f) != 1);
973
1023
 
974
1024
        if ((state & 0x1f) != 9) { // AUD NAL
975
1025
            data = av_malloc(pkt->size+6);
976
1026
            if (!data)
977
 
                return -1;
 
1027
                return AVERROR(ENOMEM);
978
1028
            memcpy(data+6, pkt->data, pkt->size);
979
1029
            AV_WB32(data, 0x00000001);
980
1030
            data[4] = 0x09;
982
1032
            buf  = data;
983
1033
            size = pkt->size+6;
984
1034
        }
985
 
    } else if (st->codec->codec_id == CODEC_ID_AAC) {
986
 
        if (pkt->size < 2)
987
 
            return -1;
 
1035
    } else if (st->codec->codec_id == AV_CODEC_ID_AAC) {
 
1036
        if (pkt->size < 2) {
 
1037
            av_log(s, AV_LOG_ERROR, "AAC packet too short\n");
 
1038
            return AVERROR(EINVAL);
 
1039
        }
988
1040
        if ((AV_RB16(pkt->data) & 0xfff0) != 0xfff0) {
989
 
            ADTSContext *adts = ts_st->adts;
990
 
            int new_size, err;
991
 
            if (!adts) {
992
 
                av_log(s, AV_LOG_ERROR, "aac bitstream not in adts format "
 
1041
            int ret;
 
1042
            AVPacket pkt2;
 
1043
 
 
1044
            if (!ts_st->amux) {
 
1045
                av_log(s, AV_LOG_ERROR, "AAC bitstream not in ADTS format "
993
1046
                       "and extradata missing\n");
994
 
                return -1;
 
1047
                return AVERROR(EINVAL);
995
1048
            }
996
 
            new_size = ADTS_HEADER_SIZE+adts->pce_size+pkt->size;
997
 
            if ((unsigned)new_size >= INT_MAX)
998
 
                return -1;
999
 
            data = av_malloc(new_size);
1000
 
            if (!data)
 
1049
 
 
1050
            av_init_packet(&pkt2);
 
1051
            pkt2.data = pkt->data;
 
1052
            pkt2.size = pkt->size;
 
1053
            ret = avio_open_dyn_buf(&ts_st->amux->pb);
 
1054
            if (ret < 0)
1001
1055
                return AVERROR(ENOMEM);
1002
 
            err = ff_adts_write_frame_header(adts, data, pkt->size,
1003
 
                                             adts->pce_size);
1004
 
            if (err < 0) {
 
1056
 
 
1057
            ret = av_write_frame(ts_st->amux, &pkt2);
 
1058
            if (ret < 0) {
 
1059
                avio_close_dyn_buf(ts_st->amux->pb, &data);
 
1060
                ts_st->amux->pb = NULL;
1005
1061
                av_free(data);
1006
 
                return err;
1007
 
            }
1008
 
            if (adts->pce_size) {
1009
 
                memcpy(data+ADTS_HEADER_SIZE, adts->pce_data, adts->pce_size);
1010
 
                adts->pce_size = 0;
1011
 
            }
1012
 
            memcpy(data+ADTS_HEADER_SIZE+adts->pce_size, pkt->data, pkt->size);
 
1062
                return ret;
 
1063
            }
 
1064
            size = avio_close_dyn_buf(ts_st->amux->pb, &data);
 
1065
            ts_st->amux->pb = NULL;
1013
1066
            buf = data;
1014
 
            size = new_size;
1015
1067
        }
1016
1068
    }
1017
1069
 
1051
1103
    return 0;
1052
1104
}
1053
1105
 
1054
 
static int mpegts_write_end(AVFormatContext *s)
 
1106
static void mpegts_write_flush(AVFormatContext *s)
1055
1107
{
1056
 
    MpegTSWrite *ts = s->priv_data;
1057
 
    MpegTSWriteStream *ts_st;
1058
 
    MpegTSService *service;
1059
 
    AVStream *st;
1060
1108
    int i;
1061
1109
 
1062
1110
    /* flush current packets */
1063
1111
    for(i = 0; i < s->nb_streams; i++) {
1064
 
        st = s->streams[i];
1065
 
        ts_st = st->priv_data;
 
1112
        AVStream *st = s->streams[i];
 
1113
        MpegTSWriteStream *ts_st = st->priv_data;
1066
1114
        if (ts_st->payload_size > 0) {
1067
1115
            mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_size,
1068
1116
                             ts_st->payload_pts, ts_st->payload_dts,
1069
1117
                             ts_st->payload_flags & AV_PKT_FLAG_KEY);
 
1118
            ts_st->payload_size = 0;
1070
1119
        }
 
1120
    }
 
1121
    avio_flush(s->pb);
 
1122
}
 
1123
 
 
1124
static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt)
 
1125
{
 
1126
    if (!pkt) {
 
1127
        mpegts_write_flush(s);
 
1128
        return 1;
 
1129
    } else {
 
1130
        return mpegts_write_packet_internal(s, pkt);
 
1131
    }
 
1132
}
 
1133
 
 
1134
static int mpegts_write_end(AVFormatContext *s)
 
1135
{
 
1136
    MpegTSWrite *ts = s->priv_data;
 
1137
    MpegTSService *service;
 
1138
    int i;
 
1139
 
 
1140
    mpegts_write_flush(s);
 
1141
 
 
1142
    for(i = 0; i < s->nb_streams; i++) {
 
1143
        AVStream *st = s->streams[i];
 
1144
        MpegTSWriteStream *ts_st = st->priv_data;
1071
1145
        av_freep(&ts_st->payload);
1072
 
        av_freep(&ts_st->adts);
 
1146
        if (ts_st->amux) {
 
1147
            avformat_free_context(ts_st->amux);
 
1148
            ts_st->amux = NULL;
 
1149
        }
1073
1150
    }
1074
 
    avio_flush(s->pb);
1075
1151
 
1076
1152
    for(i = 0; i < ts->nb_services; i++) {
1077
1153
        service = ts->services[i];
1086
1162
 
1087
1163
AVOutputFormat ff_mpegts_muxer = {
1088
1164
    .name              = "mpegts",
1089
 
    .long_name         = NULL_IF_CONFIG_SMALL("MPEG-2 transport stream format"),
 
1165
    .long_name         = NULL_IF_CONFIG_SMALL("MPEG-TS (MPEG-2 Transport Stream)"),
1090
1166
    .mime_type         = "video/x-mpegts",
1091
1167
    .extensions        = "ts,m2t",
1092
1168
    .priv_data_size    = sizeof(MpegTSWrite),
1093
 
    .audio_codec       = CODEC_ID_MP2,
1094
 
    .video_codec       = CODEC_ID_MPEG2VIDEO,
 
1169
    .audio_codec       = AV_CODEC_ID_MP2,
 
1170
    .video_codec       = AV_CODEC_ID_MPEG2VIDEO,
1095
1171
    .write_header      = mpegts_write_header,
1096
1172
    .write_packet      = mpegts_write_packet,
1097
1173
    .write_trailer     = mpegts_write_end,
1098
 
    .priv_class = &mpegts_muxer_class,
 
1174
    .flags             = AVFMT_ALLOW_FLUSH,
 
1175
    .priv_class        = &mpegts_muxer_class,
1099
1176
};