On 2/26/12 12:08 AM, Martin Storsjö wrote:
On Sat, 25 Feb 2012, Luca Barbato wrote:
After discussing with martin looks like the mpegts write_header isn't
that compatible with my segmenting approach.
This may sound rude - sorry about that, no offense meant, but... If it
isn't compatible - why not change your segmenting approach instead of
changing the mpegts write_write header? The current mpegts muxer
behaviour works just fine for me.
Because if my segmenting approach is "create a new file every N
seconds", it should create a new file by writing the header, then the
packets and then the trailer.
What sould this "short term hack" for segmenting support within the
muxer be? The muxer already has everything you need, in the
resend_headers option.
Add the private options and the logic to cut the file basically.
Also, I'm against the thing you suggest as a "long term solution", since
I think this is the wrong approach.
Unrelated to the segment situation, the current api is wrong since
doesn't differentiate between init (that could take long and be slow)
and write headers (that should be quick).
The problem, as I see it, is that the approach taken by your segmenting
muxer simply is wrong, or then I just don't understand it, since it
makes things way more complicated than they need to be.
It is straightforward. You create a new file for each segment, in order
to do that you just close the avio, set the format context to workaround
the init+write header, write the new header, the packets up to the next
segment, write the trailer making sure it doesn't dealloc more than
you'd expect, move to the next one.
If our format api gets overhauled as I like we would get
init
write header
write packets
write trailer
...
write header
write packets
write trailer
and so on.
If you want to segment mpegts (for HLS), you should not call
write_header/write_trailer. Each file in HLS is not a "individual" ts
file, they're one single stream cut into pieces. The difference is small
for mpegts, though, mostly philosophical.
That's why I prefer putting this different logic in the mpegts muxer.
The way I recommend doing it (the way I'm doing it in an external
segmenter of mine) is opening one single muxer, initializing it once,
and either closing/reopening the AVIOContext or using a custom
AVIOContext that writes the data into separate files. When switching to
a new segment file, you can set the resend_headers option to 1, to make
the muxer write all the necessary headers when writing the next packet.
Yes, that's the idea for the in-mpegts-muxer approach.
For what I've understood of your suggestion of splitting write_header
into init+write_header, the write_header part would (for mpegts) be
exactly the same as what setting the resend_headers option does today.
Yes.
Therefore, I don't understand why we would need to introduce this
concept on the general lavf level (in the longer term) as a separate
function, since I off-hand don't see a single muxer/format where it fits
in.
Every muxer would fit it, is just similar to avcodec.
In mpegts, the "headers" are written periodically within a stream
anyway. Calling write_header (even a splitted version of the function
which doesn't do init) for me is analoguous to starting a new individual
stream separate from the previous one. Setting the resend_headers option
just triggers the periodical "header" writing immediately but still
considering it the same stream as before. That's the way I view it.
Consider mkv or nut, segment should create files that can be read
independently from the others for really dumb players consuming a
playlist (e.g. a browser with some javascript magic)
For other formats, such as ismv in smooth streaming, things are way
different. There, you can either write all the fragments into one single
ismv file (which needs serverside support for serving as fragments), or
you can write the fragments into individual files for serving by a plain
normal web server. There, the segmentation/fragmentation process is like
this:
- First you write the header of the file (ftyp+moov) by calling
write_header - if writing data to one single ismv file, you write it
there, but if you write individual fragment files, this data should not
be written into any fragment at all.
- Then you write packets for the next fragment - these are buffered
within the muxer
- When you want to cut to a new fragment, you call av_write_frame(ctx,
NULL), to flush the buffered packets. This outputs one moof+mdat atom
pair, which you write into the fragment file. (For one big ismv file,
just write it to the file.)
- Repeat the last two steps for each fragment, writing into a new
fragment file each time.
- When you're finished, you call write_trailer. This writes mfra atoms
for the end of the stream - this shouldn't be written to any fragment
file either, but should be written to the ismv file.
In this case, you woulnd't be using write_header at all while writing
the packets and fragments. The fragment files are just small subsets of
the full ismv file, excluding the header (ftyp+moov) and trailer (mfra)
of the file.
Those format are a bit more smart and the serving side supposedly makes
so the player (that again should be smarter) gets the global headers
somehow.
Hypothetically, if you want to do a segmenting muxer which produces a
playlist of let's say wav files, you need to do the full write_header +
write_trailer for each file, to produce normal wav files that are
playable on their own.
Exactly.
Thus, my point is that segmenting data into separate files is a very
format specific process. Trying to generalize it is fine and admirable,
but please don't change the mpegts muxer to try to fit a different
process, when there are enough provisions for doing it just right in the
current state.
I'm trying to make the whole process clearer for the basic usage.
For advanced usage we'd need to work in the muxer or expose more muxing
details. (and that is within my plans for amf at least)
lu
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel