[FFmpeg-devel] [PATCH 7/7] lavf/mpegtsenc: add automatic bitstream filtering
Hendrik Leppkes
h.leppkes at gmail.com
Fri Dec 4 13:12:48 CET 2015
On Fri, Dec 4, 2015 at 12:31 PM, Rodger Combs <rodger.combs at gmail.com> wrote:
> ---
> libavformat/mpegtsenc.c | 65 ++++++++++++++++++++++++++-----------------------
> 1 file changed, 35 insertions(+), 30 deletions(-)
>
> diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
> index 468bad4..a8fb3a2 100644
> --- a/libavformat/mpegtsenc.c
> +++ b/libavformat/mpegtsenc.c
> @@ -698,7 +698,7 @@ static void section_write_packet(MpegTSSection *s, const uint8_t *packet)
> avio_write(ctx->pb, packet, TS_PACKET_SIZE);
> }
>
> -static int mpegts_write_header(AVFormatContext *s)
> +static int mpegts_init(AVFormatContext *s)
> {
> MpegTSWrite *ts = s->priv_data;
> MpegTSWriteStream *ts_st;
> @@ -920,26 +920,6 @@ static int mpegts_write_header(AVFormatContext *s)
>
> fail:
> av_freep(&pids);
> - for (i = 0; i < s->nb_streams; i++) {
> - st = s->streams[i];
> - ts_st = st->priv_data;
> - if (ts_st) {
> - av_freep(&ts_st->payload);
> - if (ts_st->amux) {
> - avformat_free_context(ts_st->amux);
> - ts_st->amux = NULL;
> - }
> - }
> - av_freep(&st->priv_data);
> - }
> -
> - for (i = 0; i < ts->nb_services; i++) {
> - service = ts->services[i];
> - av_freep(&service->provider_name);
> - av_freep(&service->name);
> - av_freep(&service);
> - }
> - av_freep(&ts->services);
> return ret;
> }
>
> @@ -1674,20 +1654,27 @@ static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt)
>
> static int mpegts_write_end(AVFormatContext *s)
> {
> + if (s->pb)
> + mpegts_write_flush(s);
> +
> + return 0;
> +}
> +
> +static void mpegts_deinit(AVFormatContext *s)
> +{
> MpegTSWrite *ts = s->priv_data;
> MpegTSService *service;
> int i;
>
> - if (s->pb)
> - mpegts_write_flush(s);
> -
> for (i = 0; i < s->nb_streams; i++) {
> AVStream *st = s->streams[i];
> MpegTSWriteStream *ts_st = st->priv_data;
> - av_freep(&ts_st->payload);
> - if (ts_st->amux) {
> - avformat_free_context(ts_st->amux);
> - ts_st->amux = NULL;
> + if (ts_st) {
> + av_freep(&ts_st->payload);
> + if (ts_st->amux) {
> + avformat_free_context(ts_st->amux);
> + ts_st->amux = NULL;
> + }
> }
> }
>
> @@ -1698,8 +1685,24 @@ static int mpegts_write_end(AVFormatContext *s)
> av_freep(&service);
> }
> av_freep(&ts->services);
> +}
>
> - return 0;
> +static int mpegts_check_bitstream(struct AVFormatContext *s, const AVPacket *pkt)
> +{
> + int ret = 1;
> + AVStream *st = s->streams[pkt->stream_index];
> +
> + if (st->codec->codec_id == AV_CODEC_ID_H264) {
> + if (pkt->size >= 5 && AV_RB32(pkt->data) != 0x0000001 &&
> + AV_RB24(pkt->data) != 0x000001)
> + ret = ff_stream_add_bitstream_filter(st, "h264_mp4toannexb", NULL);
> + } else if (st->codec->codec_id == AV_CODEC_ID_HEVC) {
> + if (pkt->size >= 5 && AV_RB32(pkt->data) != 0x0000001 &&
> + AV_RB24(pkt->data) != 0x000001)
> + ret = ff_stream_add_bitstream_filter(st, "hevc_mp4toannexb", NULL);
> + }
I'm not sure these checks are entirely perfect, a 4-byte length code
in mp4 style could realistically start with 0x000001xx. Maybe combine
this with a quick check for extradata? mp4 style extradata always
starts with a 0x01 byte.
> +
> + return ret;
> }
>
> static const AVOption options[] = {
> @@ -1803,9 +1806,11 @@ AVOutputFormat ff_mpegts_muxer = {
> .priv_data_size = sizeof(MpegTSWrite),
> .audio_codec = AV_CODEC_ID_MP2,
> .video_codec = AV_CODEC_ID_MPEG2VIDEO,
> - .write_header = mpegts_write_header,
> + .init = mpegts_init,
> .write_packet = mpegts_write_packet,
> .write_trailer = mpegts_write_end,
> + .deinit = mpegts_deinit,
> + .check_bitstream = mpegts_check_bitstream,
> .flags = AVFMT_ALLOW_FLUSH | AVFMT_VARIABLE_FPS,
> .priv_class = &mpegts_muxer_class,
> };
> --
> 2.6.3
>
- Hendrik
More information about the ffmpeg-devel
mailing list