Opened 6 months ago

Closed 6 months ago

#6301 closed enhancement (invalid)

Bitstream filter 'h264_mp4toannexb' isn't auto-inserted for hls muxer

Reported by: Alexander Owned by:
Priority: wish Component: avformat
Version: git-master Keywords: hls
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

There is no .check_bitstream method in hlsenc.c though it uses mpegts muxer which has this method. So setting flag AVFMT_FLAG_AUTO_BSF doesn't result in auto-inserting bitstream filters, especially h264_mp4toannexb which is needed in converting mp4 files to hls playlist.

Attachments (1)

patchhlscheckbitstream.diff (1.9 KB) - added by cehoyos 6 months ago.

Download all attachments as: .zip

Change History (12)

Changed 6 months ago by cehoyos

comment:1 Changed 6 months ago by cehoyos

  • Keywords auto-insert h264_mp4toannexb removed
  • Priority changed from normal to wish
  • Version changed from 3.2.1 to git-master

Please test attached patch.

comment:2 Changed 6 months ago by heleppkes

AVFMT_FLAG_AUTO_BSF is set by default, so the internal mpegts muxer in the HLS muxer should have this flag set, and automatically use the BSF appropriately. There is no need to run it before the HLS muxer as far as I can tell.

In fact, I just tried with Git master, and it works as expected.

Log snippet:
ffmpeg -loglevel debug -i "The Simpsons Movie - 1080p Trailer.mp4" -vcodec copy -acodec copy -sn -f hls test.m3u8

Output #0, hls, to 'test.m3u8':
  Metadata:
    major_brand     : isom
    minor_version   : 1
    compatible_brands: isomavc1
    encoder         : Lavf57.72.100
    Stream #0:0(und), 0, 1/90000: Video: h264 (High), 1 reference frame (avc1 / 0x31637661), yuv420p(left), 1920x800 (0x0), 0/1, q=2-31, 7234 kb/s, 23.98 fps, 23.98 tbr, 90k tbn, 23.98 tbc (default)
    Metadata:
      creation_time   : 2007-05-15T06:55:40.000000Z
      handler_name    : GPAC ISO Video Handler
    Stream #0:1(und), 0, 1/90000: Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default)
    Metadata:
      creation_time   : 2007-05-15T06:55:46.000000Z
      handler_name    : GPAC ISO Audio Handler
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help
cur_dts is invalid (this is harmless if it occurs once at the start per stream)
    Last message repeated 15 times
Automatically inserted bitstream filter 'h264_mp4toannexb'; args=''
[AVIOContext @ 03f87e40] Statistics: 0 seeks, 117 writeouts
[file @ 0405a1c0] Setting default whitelist 'file,crypto'
[file @ 04059a20] Setting default whitelist 'file,crypto'
[hls muxer @ 04004600] EXT-X-MEDIA-SEQUENCE:0

(Relevant line: Automatically inserted bitstream filter 'h264_mp4toannexb'; args=)

comment:3 Changed 6 months ago by Alexander

Ok, I was wrong and there are really

Automatically inserted bitstream filter 'h264_mp4toannexb'; args=''

messages in logs. But still AVFMT_FLAG_AUTO_BSF flag doesn't work for me and I must create bitstream filter by hands :(

I use ffmpeg library API, converting mp4 files to HLS playlist without decoding/encoding frames, only demux/mux. My workflow:

  1. Create AVFormatContext with avformat_alloc_output_context2 and 'hls' as format
  2. Create streams in it with avformat_new_stream(format_context, codec);
  3. Open streams with:
    AVCodecContext *codec_context = avcodec_alloc_context3(codec);
    // setup codec_context here
    avcodec_parameters_from_context(stream->codecpar, codec_context);
    avcodec_open2(codec_context, codec, NULL);
    
  4. Set flag
    format_context->flags |= AVFMT_FLAG_AUTO_BSF
    
  5. Begin write with avformat_write_header(format_context, NULL);
  6. Begin standard loop with av_read_frame and av_interleaved_write_frame.

Currently, on the last step I apply 'h264_mp4toannexb' manually with av_bsf_send_packet and av_bsf_receive_packet. I'd like to use auto-insert instead, but it doesn't work for me. I receive next messages:

[AVBSFContext @ 0x80afff100] [verbose] The input looks like it is Annex B already
[verbose] Automatically inserted bitstream filter 'h264_mp4toannexb'; args=''
[mpegts @ 0x807ffd800] [error] H.264 bitstream malformed, no startcode found, use the video bitstream filter 'h264_mp4toannexb' to fix it ('-bsf:v h264_mp4toannexb' option with ffmpeg)
Last edited 6 months ago by Alexander (previous) (diff)

comment:4 Changed 6 months ago by heleppkes

The first message (The input looks like it is Annex B already) suggests you are feeding it something odd, it thinks its AnnexB already (possibly from extradata?), and then doesn't convert anything.

So make sure its either full MP4-format (including extradata), or full AnnexB.

comment:5 Changed 6 months ago by Alexander

As it can be seen from my workflow, I create target streams manually, so there is no extradata in them.

If I understand correctly, auto-inserting bitstream filter depends on output format context (and its streams) because we must know output format to check if we need to auto insert filter. But for correct work 'h264_mp4toannexb' needs extradata from input stream. So I must copy extradata from input stream to output stream or, if there is no one source of frames (my case), don't rely on auto-inserting, filter frames manually and write already Annex B frames.

comment:6 Changed 6 months ago by heleppkes

If you have frames in MP4 format, then the extradata is absolutely required, because only with the extradata the MP4 format can even be interpreted properly! It contains mandatory information required by the BSF, or even any decoder.

So no matter how you do the conversion, you do need to have extradata at hand to do it.

comment:7 Changed 6 months ago by Alexander

As about suggested patch - unfortunately, it doesn't help.

comment:8 Changed 6 months ago by Alexander

2heleppkes: I have extradata, but it is in frame source streams, not in output stream. And extradata is different for different sources. So I can't copy it to output stream which, as I can see, is needed for auto-insert filter to work.

If I filter streams manually and put Annex B frames to output stream - all works fine even without extradata in output stream.

comment:9 Changed 6 months ago by Alexander

I think this ticket can be closed. It'll be good to add to documentation that copying of extradata from input stream to output stream may be needed for auto-insert filter to work (at least for 'h264_mp4toannexb').

comment:10 Changed 6 months ago by Cigaes

I think you misunderstand how it works. The HLS muxer does not know anything about your input or your output, that is the responsibility of your program. Therefore, adding "from input stream to output stream" to the documentation would be nonsense.

The HLS muxer only sees the streams you want to mux. These streams can be in various formats, including:

  • H.264-in-Annex_B-format (stand-alone packets, no extradata);
  • H.264-in-MP4-format (slightly smaller packets, extradata).

If you are providing H.264-in-MP4-format without the extradata, you are providing invalid input to the muxer, exactly as if you filled the packets' data with random octets.

Now, where does the extradata come from? The same place as the packets' data, and the demuxer does not care.

If the packets come from FFmpeg, a demuxer or an encoder, then the extradata is there too, because FFmpeg does things correctly, or more precisely consistently.

If the packets come from anywhere else, then that is your responsibility to make sure they come with their extradata.

comment:11 Changed 6 months ago by cehoyos

  • Resolution set to invalid
  • Status changed from new to closed
Note: See TracTickets for help on using tickets.