Commit Graph

41 Commits

Author SHA1 Message Date
Peter Große 01f1f017d8 dashenc: use avio_dynbuf instead of packet_write callback
The dash_write function drops data, if no IOContext is initialized.

Since the mp4 muxer is used in "frag_custom" mode, data is only
written when calling av_write_frame(NULL) explicitly and thus
there will be no data loss.

To add support for webm as subordinate muxer, which doesn't have
such a mode, a dynamic buffer is required to provide an always
initialized IOContext.

Signed-off-by: Peter Große <pegro@friiks.de>
Signed-off-by: Martin Storsjö <martin@martin.st>
2017-01-31 00:38:29 +02:00
Peter Große dce2929efa dashenc: copy language and role metadata from streams assigned to sets
Signed-off-by: Peter Große <pegro@friiks.de>
Signed-off-by: Martin Storsjö <martin@martin.st>
2017-01-31 00:38:28 +02:00
Peter Große ca9bc9de69 dashenc: default to one AdaptationSet per stream
Previously all mapped streams of a media type (video, audio) where assigned
to a single AdaptationSet. Using the DASH live profile it is mandatory, that
the segments of all representations are aligned, which is currently not
enforced. This leads to problems when using video streams with different
key frame intervals. So to play safe, default to one AdaptationSet per stream,
unless overwritten by explicit assignment.

To get the old assignment scheme, use

  -adaptation_sets "id=0,streams=v id=1,streams=a"

Signed-off-by: Peter Große <pegro@friiks.de>
Signed-off-by: Martin Storsjö <martin@martin.st>
2017-01-31 00:33:07 +02:00
Peter Große efd2fc41b3 dashenc: allow assigning all streams of a media type to an AdaptationSet
Using the characters "v" or "a" instead of stream index numbers for assigning
streams in the adaption_set option, all streams matching that given type will
be added to the AdaptationSet.

Signed-off-by: Peter Große <pegro@friiks.de>
Signed-off-by: Martin Storsjö <martin@martin.st>
2017-01-31 00:24:14 +02:00
Peter Große 3d23a5f96a dashenc: add support for assigning streams to AdaptationSets
Also makes sure all streams are assigned to exactly one AdaptationSet.

This patch is originally based partially on code by Vignesh Venkatasubramanian.

Signed-off-by: Peter Große <pegro@friiks.de>
Signed-off-by: Martin Storsjö <martin@martin.st>
2017-01-31 00:22:00 +02:00
Peter Große 9df9309d23 dashenc: calculate stream bitrate from first segment if not available
Bandwidth information is required in the manifest, but not always
provided by the demuxer. In that case calculate the bandwith based
on the size and duration of the first segment.

Signed-off-by: Peter Große <pegro@friiks.de>
Signed-off-by: Martin Storsjö <martin@martin.st>
2017-01-31 00:08:21 +02:00
Peter Große e519dcd937 dashenc: separate segments based on current segment duration
The current implementation creates new segments comparing

  pkt->pts - first_pts > nb_segs * min_seg_duration

This works fine, but if the keyframe interval is smaller than "min_seg_duration"
segments shorter than the minimum segment duration are created.

Example: keyint=50, min_seg_duration=3000000
 segment 1 contains keyframe 1 (duration=2s <  total_duration=3s)
                and keyframe 2 (duration=4s >= total_duration=3s)
 segment 2 contains keyframe 3 (duration=6s >= total_duration=6s)
 segment 3 contains keyframe 4 (duration=8s <  total_duration=9s)
                and keyframe 5 (duration=10s >= total_duration=9s)
 ...

Segment 2 is only 2s long, shorter than min_seg_duration = 3s.

To fix this, new segments are created based on the actual written duration.
Otherwise the option name "min_seg_duration" is misleading.

Signed-off-by: Peter Große <pegro@friiks.de>
Signed-off-by: Martin Storsjö <martin@martin.st>
2017-01-31 00:08:21 +02:00
Peter Große 1920382aa9 dashenc: add option to provide UTC timing source
If set, adds a UTCTiming tag in the manifest.

This is part of the recommendations listed in the "Guidelines for
Implementations: DASH-IF Interoperability Points" [1][2]
Section 4.7 describes means for the Availability Time Synchronization.

A usable default is "https://time.akamai.com/?iso"

[1] http://dashif.org/guidelines/
[2] http://dashif.org/wp-content/uploads/2016/12/DASH-IF-IOP-v4.0-clean.pdf
    (current version as of writing)

Signed-off-by: Peter Große <pegro@friiks.de>
Signed-off-by: Martin Storsjö <martin@martin.st>
2017-01-31 00:08:09 +02:00
Anton Schubert 3c2717e48d dashenc: increase buffer time hint in the manifest
to avoid rebuffering on the clientside for difficult network conditions.

Signed-off-by: Anton Schubert <ischluff@mailbox.org>
Signed-off-by: Martin Storsjö <martin@martin.st>
2017-01-27 14:34:17 +02:00
Peter Große 95f1004bdf dashenc: add mandatory id to AdaptationSet and Period in manifest
Signed-off-by: Peter Große <pegro@friiks.de>
Signed-off-by: Martin Storsjö <martin@martin.st>
2017-01-27 14:27:40 +02:00
Anton Schubert 1ae6cb7d6e dashenc: fix ISO8601 UTC parsing
Appends Z to timestamp to force ISO8601 datetime parsing as UTC.
Without Z, some browsers (Chrome) interpret the timestamp as
localtime and others (Firefox) interpret it as UTC.

Signed-off-by: Anton Schubert <ischluff@mailbox.org>
Signed-off-by: Martin Storsjö <martin@martin.st>
2017-01-27 14:07:30 +02:00
Diego Biurrun 07cac07c0c dash: Use correct ISO C scanf conversion specifier 2016-10-28 13:29:52 +02:00
Anton Khirnov 9200514ad8 lavf: replace AVStream.codec with AVStream.codecpar
Currently, AVStream contains an embedded AVCodecContext instance, which
is used by demuxers to export stream parameters to the caller and by
muxers to receive stream parameters from the caller. It is also used
internally as the codec context that is passed to parsers.

In addition, it is also widely used by the callers as the decoding (when
demuxer) or encoding (when muxing) context, though this has been
officially discouraged since Libav 11.

There are multiple important problems with this approach:
    - the fields in AVCodecContext are in general one of
        * stream parameters
        * codec options
        * codec state
      However, it's not clear which ones are which. It is consequently
      unclear which fields are a demuxer allowed to set or a muxer allowed to
      read. This leads to erratic behaviour depending on whether decoding or
      encoding is being performed or not (and whether it uses the AVStream
      embedded codec context).
    - various synchronization issues arising from the fact that the same
      context is used by several different APIs (muxers/demuxers,
      parsers, bitstream filters and encoders/decoders) simultaneously, with
      there being no clear rules for who can modify what and the different
      processes being typically delayed with respect to each other.
    - avformat_find_stream_info() making it necessary to support opening
      and closing a single codec context multiple times, thus
      complicating the semantics of freeing various allocated objects in the
      codec context.

Those problems are resolved by replacing the AVStream embedded codec
context with a newly added AVCodecParameters instance, which stores only
the stream parameters exported by the demuxers or read by the muxers.
2016-02-23 17:01:58 +01:00
Anton Khirnov d082078a88 dashenc: eliminate ffurl_* usage
Now all IO should go through the IO callbacks and be interceptable by
the caller.
2016-02-22 11:29:00 +01:00
Anton Khirnov 9f61abc811 lavf: allow custom IO for all files
Some (de)muxers open additional files beyond the main IO context.
Currently, they call avio_open() directly, which prevents the caller
from using custom IO for such streams.

This commit adds callbacks to AVFormatContext that default to
avio_open2()/avio_close(), but can be overridden by the caller. All
muxers and demuxers using AVIO are switched to using those callbacks
instead of calling avio_open()/avio_close() directly.

(de)muxers that use the URLProtocol layer directly instead of AVIO
remain unconverted for now. This should be fixed in later commits.
2016-01-24 16:45:32 +01:00
Martin Storsjö b8d2630c53 dashenc: Reduce the segment duration if cutting out parts with edit lists
This makes sure that the time + duration of the first segment
matches the start time of the next segment for e.g. AAC audio
with encoder delay.

Signed-off-by: Martin Storsjö <martin@martin.st>
2015-05-10 22:57:21 +03:00
James Almer ac1a1cb948 dashenc: replace attribute id with contentType for the AdaptationSet element
id should be an integer, not a string. It is also optional, so use
contentType instead which is the proper attribute for these values.

This fixes an MPD validation error.

Signed-off-by: James Almer <jamrial@gmail.com>
Signed-off-by: Martin Storsjö <martin@martin.st>
2015-05-10 22:57:20 +03:00
Martin Storsjö 2cc3936599 dashenc: Add a publishTime field in dynamic manifests
This field is mandatory in dynamic manifests.

Signed-off-by: Martin Storsjö <martin@martin.st>
2015-04-20 13:16:45 +03:00
Martin Storsjö 3041183677 dashenc: Heuristically fill in the duration of packets that need it
This avoids that the mp4 muxer does a similar heuristic, adjusting
the timestamps in a way that the dash muxer doesn't know the actual
timestamps written to the file in the end. By making sure that the
mp4 muxer internal heuristic isn't applied, we know the exact
timestamps written to file, so that the timestamps in manifest match
the files.

Signed-off-by: Martin Storsjö <martin@martin.st>
2015-03-19 10:27:03 +02:00
Timo Rothenpieler 5aef535a64 dashenc: Update extradata for mov muxer
The mov muxer already supports picking up extradata that wasn't
present during the avformat_write_header call - we just need to
propagate it. Since the dash muxer uses delay_moov, we have time
up until the first segment is written to get extradata filled in.

Also update the codec description string when the extradata becomes
available.

Signed-off-by: Martin Storsjö <martin@martin.st>
2015-03-06 10:07:17 +02:00
Timo Rothenpieler 6cf7f30655 dashenc: Simplify code by using a local variable
Signed-off-by: Martin Storsjö <martin@martin.st>
2015-03-06 10:07:11 +02:00
Martin Storsjö 33d412eb4a dashenc: Simplify code by using a local variable
Signed-off-by: Martin Storsjö <martin@martin.st>
2015-03-02 20:34:43 +02:00
Martin Storsjö 8e32b1f096 libavformat: Use ffio_free_dyn_buf where applicable
Signed-off-by: Martin Storsjö <martin@martin.st>
2015-02-24 23:07:47 +02:00
Martin Storsjö 3a724a7f3b dashenc: Use inttypes.h macros for format strings instead of %lld
Signed-off-by: Martin Storsjö <martin@martin.st>
2015-01-22 08:49:41 +02:00
Rodger Combs 1d8aa23794 dashenc: Fix format string generation
Previously this always used the "lld" format for all parameters,
not only time parameters.

Signed-off-by: Martin Storsjö <martin@martin.st>
2015-01-22 08:49:39 +02:00
Martin Storsjö 46808fdf04 movenc: Enable editlists by default if delay_moov is enabled
Being able to write editlists properly is one of the main points
in the delay_moov flag.

Signed-off-by: Martin Storsjö <martin@martin.st>
2015-01-04 20:04:36 +02:00
Martin Storsjö 7a1a63e34f dashenc: Use pts for MPD timeline timestamps
This should be more correct. This also should give more sensible
switching between video streams with different amount of b-frame
delay.

The current dash.js release (1.2.0) fails to start playback of
such files from the start (if the start pts is > 0), but this has
been fixed in the current git version of dash.js.

Also enable the use of edit lists, so that streams in many cases
start at pts=0.

Signed-off-by: Martin Storsjö <martin@martin.st>
2015-01-03 01:22:09 +02:00
Martin Storsjö c5e7ea13d2 dashenc: Use delay_moov
Signed-off-by: Martin Storsjö <martin@martin.st>
2015-01-03 01:20:55 +02:00
Martin Storsjö 8d54bacb78 dashenc: Remove some stray double spaces
Signed-off-by: Martin Storsjö <martin@martin.st>
2014-12-29 23:26:43 +02:00
Martin Storsjö b91a5757fc dashenc: Fix writing of timelines that don't start at t=0
When writing an explicit time, reset the cur_time variable to this
value as well. This avoids writing excessive time attributes for each
segment in the timeline, as long as the segments are continuous.

Signed-off-by: Martin Storsjö <martin@martin.st>
2014-12-29 23:26:25 +02:00
Martin Storsjö 456e93bfdd dashenc: Adjust the start time of a segment to the end of the previous segment
This is the same adjustment that the mp4 muxer does to the start
timestamp of fragments, since the timestamp of a sample in an mp4
file is implicit from the sum of earlier sample durations.

This avoids gaps in the timeline (which can stop dash.js from
playing it back), and makes sure the timestamp on the segmenter
level matches what the mp4 muxer actually writes into the segments.

This is only an issue if the AVPacket duration of the last
packet of a segment doesn't point to the actual start timestamp
of the next packet (the first in the next segment).

Signed-off-by: Martin Storsjö <martin@martin.st>
2014-12-17 09:43:08 +02:00
Martin Storsjö 2f628d5943 dashenc: Write segment timelines properly if the timeline has gaps
Write a new start time if the duration of the previous segment
didn't match the start of the next one. Check that segments
actually are continuous before writing a repeat count.

This makes sure timestamps deduced from the timeline actually
match the real start timestamp as written in filenames (if
using a template containing $Time$).

Signed-off-by: Martin Storsjö <martin@martin.st>
2014-12-17 09:42:30 +02:00
Martin Storsjö e737a4aaaf dashenc: Change the duration fields to 64 bit
For the last_duration field, it's mostly theoretical, but the
total_duration field more probably may need to actually be 64 bit.

Bug-Id: CID 1254944
Signed-off-by: Martin Storsjö <martin@martin.st>
2014-12-10 22:51:51 +02:00
Bryan Huh fa8934d6d6 dashenc: log file output progress in verbose mode
As the manifest/segments are flushed to disk, log to stderr the
progress, when in verbose logging mode

Signed-off-by: Martin Storsjö <martin@martin.st>
2014-12-10 00:03:16 +02:00
Martin Storsjö fcae9f212a dashenc: Avoid a VLA-like construct
This fixes the build on compilers that interpreted the earlier
code as a variable length array (which we intentionally disallow).

Signed-off-by: Martin Storsjö <martin@martin.st>
2014-11-28 11:55:42 +02:00
Bryan Huh a9d8d35e48 dashenc: Add options to make segment names configurable
This allows one to specify templated segment names for init-segments,
media-segments, and for the base-url in the case of single-file.

Signed-off-by: Martin Storsjö <martin@martin.st>
2014-11-28 10:48:15 +02:00
Martin Storsjö 675ac56b7e Revert "lavf: Don't try to update files atomically with renames on windows"
This reverts commit b9d08c77a4.

After taking MoveFileEx into use, we can replace files with renames
on windows as well.

Signed-off-by: Martin Storsjö <martin@martin.st>
2014-11-27 09:29:47 +02:00
Martin Storsjö b9d08c77a4 lavf: Don't try to update files atomically with renames on windows
On windows, rename(2) will fail if the target file exists. On
unix this trick is used to make sure that people reading the file
either will get the full previous file, or the full new version
of the file, but no intermediate version.

Signed-off-by: Martin Storsjö <martin@martin.st>
2014-11-24 23:34:44 +02:00
Martin Storsjö fe42f94ce1 dashenc: Don't segment all video streams when one stream gets a keyframe
This makes sure that segments actually start at a keyframe (and
makes sure we don't split segments twice in a row, with one segment
consisting of only a handful of packets), when one stream uses b-frames
while another one doesn't.

Signed-off-by: Martin Storsjö <martin@martin.st>
2014-11-24 11:09:40 +02:00
Martin Storsjö f856d9c2f3 dashenc: Don't require the stream bitrate to be known
Don't write any bitrate attribute if it isn't known. As long as one
doesn't want automatic bitrate switching, playback can work just
fine even if it isn't set.

If strict standard compliance is requested, this is still considered
an error, since the attribute is mandatory according to the spec.

Based on a patch by Rodger Combs.

Signed-off-by: Martin Storsjö <martin@martin.st>
2014-11-22 22:16:37 +02:00
Martin Storsjö fe5e6e34c0 lavf: Add an MPEG-DASH ISOFF segmenting muxer
This is mostly to serve as a reference example on how to segment
the output from the mp4 muxer, capable of writing the segment
list in four different ways:
- SegmentTemplate with SegmentTimeline
- SegmentTemplate with implicit segments
- SegmentList with individual files
- SegmentList with one single file per track, and byte ranges

The muxer is able to serve live content (with optional windowing)
or create a static segmented MPD.

In advanced cases, users will probably want to do the segmenting
in their own application code.

Signed-off-by: Martin Storsjö <martin@martin.st>
2014-11-17 16:17:07 +02:00