Commit bf835128 authored by Timothy B. Terriberry's avatar Timothy B. Terriberry Committed by Jean-Baptiste Kempf

Opus demuxing fixes.

This properly handles pre-skip, seeking pre-roll, and end-trim. It
uses the i_nb_samples field of block_t to signal to the decoder how
many samples should be returned after (possibly) skipping some at
the start of the block (for both pre-skip and pre-roll). In
addition, it abuses the i_length field of block_t to signal to the
decoder how many samples to trim from the end of the packet (for
end-trimming).

This patch does not compute correct timestamps for streams which
start at a non-zero offset (e.g., live streams joined in the
middle), nor does it correctly compute the length of a stream. But
neither of those things work for Vorbis, either. I'm leaving them
for a follow-up patch.
Signed-off-by: default avatarRafaël Carré <funman@videolan.org>
(cherry picked from commit 675072a8a6a520f79e9892e26ff3be98b069df7a)
Signed-off-by: default avatarJean-Baptiste Kempf <jb@videolan.org>
parent 410a1013
This diff is collapsed.
......@@ -55,6 +55,7 @@ typedef struct logical_stream_s
int i_packets_backup;
void *p_headers;
int i_headers;
ogg_int64_t i_previous_granulepos;
/* program clock reference (in units of 90kHz) derived from the previous
* granulepos */
......@@ -67,6 +68,8 @@ typedef struct logical_stream_s
int i_granule_shift;
/* Opus has a starting offset in the headers. */
int i_pre_skip;
/* Vorbis and Opus can trim the end of a stream using granule positions. */
int i_end_trim;
/* offset of first keyframe for theora; can be 0 or 1 depending on version number */
int64_t i_keyframe_offset;
......
......@@ -772,14 +772,26 @@ int oggseek_find_frame ( demux_t *p_demux, logical_stream_t *p_stream, int64_t i
i_tframe += p_stream->i_keyframe_offset;
i_cframe = i_tframe;
/* For Opus, seek back 80 ms before the target playback position. */
if ( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
{
if ( i_tframe <= p_stream->i_pre_skip )
i_cframe = 0;
else if ( i_tframe < 80*48 )
i_cframe = 0;
else
i_cframe = i_tframe - 80*48;
}
/* reduce the search domain */
fidx = get_bounds_for( p_stream, i_tframe, &i_pos_lower, &i_pos_upper );
fidx = get_bounds_for( p_stream, i_cframe, &i_pos_lower, &i_pos_upper );
if ( fidx == NULL )
{
/* no exact match found; search the domain for highest keyframe <= i_tframe */
/* no exact match found; search the domain for highest keyframe <= i_cframe */
i_granulepos = ogg_seek ( p_demux, p_stream, i_tframe, i_pos_lower, i_pos_upper,
i_granulepos = ogg_seek ( p_demux, p_stream, i_cframe, i_pos_lower, i_pos_upper,
&i_pagepos, true );
if ( i_granulepos == -1 )
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment