This bug caused properties that should be associated with the different
tracks (such as es_format_t.i_priority) to be written to a local copy,
instead of actually propagating to where they should be.
Signed-off-by: Thomas Guillem <thomas@gllm.fr>
Some files do not have their first cluster at PTS=0, meaning that we
might spend an eternity looking for such PTS (even though it is not at
all present in the file) when starting playback (seeking to 0).
This patch fixes the issue by always assigning a seekpoint for PTS=0 pointing
at the first cluster position. Instead of using the cluster-timecode, a
hardcoded value of 0 is used (so that every file will have a seekpoint at that
location).
Signed-off-by: Thomas Guillem <thomas@gllm.fr>
The logic for precise and inprecise seeking is the same with the
addition that precise seeking should use the exact desired timestamp
to use with ES_OUT_SET_NEXT_DISPLAY_TIME, whereas inprecise seeking will
use the timestamp associated with the closest index frame.
Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
When seeking, we should prioritize tracks depending on what type of ES
they are; this patch addes a data-member to matroska_segment_c that will
keep track of which tracks are more important than other.
It also adds logic to ComputePriorityTracks that will initialize this
data-member with the appropriate track-ids.
Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
Even though there are currently some type of cues that we cannot handle,
we should add the aprox. location denoted by such cues as a seekpoint to
optimize seeking.
Adding the location with Seekpoint::DISABLED means that we will never
seek directly to the position, but it can be used as a hint when looking
for an appropriate keyframe during the preparation for seeking.
Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
Every cue in the matroska format is based on the location of the cluster
in which it is part of, as such we should add this information (cluster
position) to the code responsible for seeking.
Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
since we require two different ways of seeking depending on
DEMUX_SET_POSITION and DEMUX_SET_TIME has been recieved with precise
seeking or not, we now have two different seek functions within
matroska_segment_c.
The theory is quite simple:
- matroska_segment_c::FastSeek is for future use
- matroska_segment_c::Seek will find the lowest correct seekpoint
for all our tracks combined, but set track.i_skip_until_fpos to
the first block that needs to be decoded for a certain track.
This means that decoding will start at the right location for
every track, without us having to worry about decoding too much
data for tracks that does not require such.
Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
Currently there are issues outside of the demuxer that does not allow us
to display an "on-going" subtitle if we seek to a location where a
subtitle has started, but yet finished.
Since there are several mkv files in the wild where there is no proper
mkv-cue for every subtitle, we should add every subtitle block we see as
an index; and then use this for seeking (if we know about it, and have
to).
In general, every subtitle block is effectively a "keyframe"; meaning
that this hack is safe (at least enough to justify its purpose). Having
seekpoints for the subtitle track will allow us to send it to the
relevant decoder, and after we have support for "unfinished" subtitles;
mkv's will magically play along nicely.
Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
This patch simply utilizes the new functionality introduced in
matroska_segment_seeker.{hpp,cpp} to store seekpoints found during
playback/preloading.
Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
- Moved variables to a more narrow scope (where they belong)
- Properly ignore cue types that we currently cannot handle correctly
(since doing otherwise will lead to unexpected (and wrong) behavior
further down the road).
This should be fixed, but the changes required are rather big; and a
discussion regarding just how we should handle the relevant matroska
elements is necesary.
Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
matroska_segment_c::Select and matroska_segment_c::Unselect are used to
create/destroy ESs, with that said they are better named ESCreate and
ESDestroy.
Given their name and functionality there is no need (or reason) to send
ES_OUT_SET_NEXT_DISPLAY_TIME from the creator, nor is it necessary to
jump to some particular file-offset (since this is handled by a call to
code that invokes seek in the relevant places).
Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
We are always calling matroska_segment_c::Seek after this function
(matroska_segment_c::Select) is called, as such there is absolutely no
need for us to explicitly invoke ES_OUT_SET_NEXT_DISPLAY_TIME (since
this will happen implicitly later).
Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
Managing the tracks by a std::vector has been replaced with a std::map
mapping the track-number to a mkv_track_t.
This patch includes changing BlockFindTrackIndex to FindTrackByBlock,
keeping the same behaviour though using a more accurate name for the new
code.
Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
Since indexing is now managed by matroska_segment_seeker.{hpp,cpp},
there is no need for the legacy functionality and data-members.
Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
It is quite obvious that we should append every Cluster as index, this
includes when doing work during Preload.
Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
If FAST_SEEK is enabled we can "preload" the location of all the
clusters when first opening our file in order to speed up seeking at a
later time.
Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
This code has been removed since it does not aid us in any way (besides
cluttering up the implementation with a data-member that we do not
really care about).
In the future we should respect the relevant matroska element, but
currently there is no point for us to care about it given the demuxers
overall state.
Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
This variable is of no real aid, as such it has been removed to favor
readability. The less fuzz around what we actually need, the better.
Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
This particular block as heen disabled for a long time, and the
rationale for disabling it with a preprocessor check is that it would
clogger the output during playback with a lot of unnecessary output.
Legacy code should be removed instead of disabled.
Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
This patch will protect us from seeking too far if a mkv-files contains
Cues that are not in ascending order.
Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
It somehow slipped my mind that C++03 disallows local types as
template-arguments, which makes one of the earlier commits invalid when
compiled as C++03.
This patch correctly moves the type in question to the global namespace
(inside an anonymous namespace to not pollute the global linkage scope)
so that everything is 100% legal C++03.
Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
Replaced the dynamic allocation with an equivalent construction on the
stack (we do not need dynamic life time since it is unconditionally
destroyed at the end of the block).
Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
Added an if-check to make sure that we do not crash on the lines that
follow if we, for some reason, end up in a state where there is no
matching seekpoint for the specified `i_track`.
Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
In order to provide better runtime safety manual management of dynamic
memory has been removed from `class Tags` and `class SimpleTags`.
This includes introducing usage of `std::vector` as well as
`std::string`, while also removing data-members that are no longer
required.
- SimpleTag::b_default has been removed since it was written to (at
once place), but never read; the write has been replaced by a comment.
- The ParseSimpleTag function has been changed to return `bool` instead
of a pointer to signal whether parsing was successful. The result
will be written to `pout_simple` (instead of being indirectly
returned through a pointer).
Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
As written in the commit title, a few uses of dynamic memory management
has been removed, effectivelly fixing a memory leak as well as making
the code cleaner/faster.
Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
Manually managing memory comes at a cost of both maintainability (in
terms of safety) and performance, as such I have replaced `p_indexes`
with a `std::vector` with equivalent functionality.
Three helper member-functions have been introduced in order to clean up
the usage of the functionality, as well as removal of two now obsolete
member-variables. A `typedef` has also been introduced to aid future
development.
The changes in `mkv.cpp` are due to the fact that it needs access to the
indexes present in `matroska_segment_c`; this should be refactored away
in the future.
Also fixed a bug where you would access index out of bounds if there
are no known indexes.
Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
I wrote a hackish script to locate instances where new can throw
but where the original author has assumed that it will return
nullptr when there is a memory allocation problem.
In short, cases such as `ptr = new T; if (ptr) ...` has now
been changed to `ptr = new (std::nothrow) T; if (ptr) ...`.
Since a throwing `new` will always yield a non-nullptr pointer,
code that follows similar patterns to the previous example are
therefor redundant.
Example (from modules/access/dshow/filter.cpp):
*ppEnum = new CaptureEnumMediaTypes( p_input, p_pin, this );
if( *ppEnum == NULL )
return E_OUTOFMEMORY; // unreachable, new will never return NULL
Fixed:
*ppEnum = new (std::nothrow) CaptureEnumMediaTypes( p_input, p_pin, this );
if( *ppEnum == NULL )
return E_OUTOFMEMORY;
Signed-off-by: Hugo Beauzée-Luyssen <hugo@beauzee.fr>