diff --git a/helpers/DATA/vlc/46fe18b280ed5825fd701edeedb2f5c24de001a2_without_xiph.patch b/helpers/DATA/vlc/46fe18b280ed5825fd701edeedb2f5c24de001a2_without_xiph.patch new file mode 100644 index 0000000000000000000000000000000000000000..204ca92730204ce8a15af7411a6801308295c6a9 --- /dev/null +++ b/helpers/DATA/vlc/46fe18b280ed5825fd701edeedb2f5c24de001a2_without_xiph.patch @@ -0,0 +1,243 @@ +From 46fe18b280ed5825fd701edeedb2f5c24de001a2 Mon Sep 17 00:00:00 2001 +From: Denis Charmet <typx@dinauz.org> +Date: Sat, 9 Nov 2013 16:53:06 +0100 +Subject: [PATCH] Implement basic Opus support in MKV + +--- + modules/codec/opus.c | 5 ++++ + modules/demux/mkv/matroska_segment.cpp | 22 +++++++++++++++- + modules/demux/mkv/matroska_segment_parse.cpp | 36 +++++++++++++++++++++++++ + modules/demux/mkv/mkv.cpp | 39 +++++++++++++++++++--------- + modules/demux/mkv/mkv.hpp | 6 +++-- + 5 files changed, 94 insertions(+), 16 deletions(-) + +diff --git a/modules/codec/opus.c b/modules/codec/opus.c +index d4e5f88..8802d49 100644 +--- a/modules/codec/opus.c ++++ b/modules/codec/opus.c +@@ -386,6 +386,11 @@ static block_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket, + if(spp>0)spp*=opus_packet_get_samples_per_frame(p_oggpacket->packet,48000); + if(spp<120||spp>120*48)return NULL; + ++ /* Since the information isn't always available at the demux level ++ * use the packet's sample number */ ++ if(!i_nb_samples) ++ i_nb_samples = spp; ++ + block_t *p_aout_buffer=decoder_NewAudioBuffer( p_dec, spp ); + if ( !p_aout_buffer ) + { +diff --git a/modules/demux/mkv/matroska_segment.cpp b/modules/demux/mkv/matroska_segment.cpp +index 756a9c5..5e71206 100644 +--- a/modules/demux/mkv/matroska_segment.cpp ++++ b/modules/demux/mkv/matroska_segment.cpp +@@ -929,10 +929,22 @@ void matroska_segment_c::Seek( mtime_t i_date, mtime_t i_time_offset, int64_t i_ + /* now parse until key frame */ + const int es_types[3] = { VIDEO_ES, AUDIO_ES, SPU_ES }; + i_cat = es_types[0]; ++ mtime_t i_seek_preroll = 0; + for( int i = 0; i < 2; i_cat = es_types[++i] ) + { + for( i_track = 0; i_track < tracks.size(); i_track++ ) + { ++ if( tracks[i_track]->i_seek_preroll ) ++ { ++ bool b_enabled; ++ if( es_out_Control( sys.demuxer.out, ++ ES_OUT_GET_ES_STATE, ++ tracks[i_track]->p_es, ++ &b_enabled ) == VLC_SUCCESS && ++ b_enabled ) ++ i_seek_preroll = __MAX( i_seek_preroll, ++ tracks[i_track]->i_seek_preroll ); ++ } + if( tracks[i_track]->fmt.i_cat == i_cat ) + { + spoint * seekpoint = new spoint(i_track, i_seek_time, i_seek_position, i_seek_position); +@@ -968,7 +980,7 @@ void matroska_segment_c::Seek( mtime_t i_date, mtime_t i_time_offset, int64_t i_ + es_out_Control( sys.demuxer.out, ES_OUT_SET_NEXT_DISPLAY_TIME, i_date ); + return; + } +- ++ i_date -= i_seek_preroll; + for(;;) + { + do +@@ -1201,6 +1213,7 @@ int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_s + *pb_key_picture = true; + *pb_discardable_picture = false; + size_t i_tk; ++ *pi_duration = 0; + + for( ;; ) + { +@@ -1407,6 +1420,13 @@ int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_s + } + } + } ++#if LIBMATROSKA_VERSION >= 0x010401 ++ else if( MKV_IS_ID( el, KaxDiscardPadding ) ) ++ { ++ KaxDiscardPadding &dp = *(KaxDiscardPadding*) el; ++ *pi_duration -= int64(dp); ++ } ++#endif + break; + default: + msg_Err( &sys.demuxer, "invalid level = %d", i_level ); +diff --git a/modules/demux/mkv/matroska_segment_parse.cpp b/modules/demux/mkv/matroska_segment_parse.cpp +index c9d2c9d..7b4c359 100644 +--- a/modules/demux/mkv/matroska_segment_parse.cpp ++++ b/modules/demux/mkv/matroska_segment_parse.cpp +@@ -30,6 +30,7 @@ + + extern "C" { + #include "../vobsub.h" ++#include "../xiph.h" + } + + #include <vlc_codecs.h> +@@ -401,6 +402,21 @@ void matroska_segment_c::ParseTrackEntry( KaxTrackEntry *m ) + + msg_Dbg( &sys.demuxer, "| | | + Track Overlay=%u", uint32( tovr ) ); + } ++#if LIBMATROSKA_VERSION >= 0x010401 ++ else if( MKV_IS_ID( l, KaxCodecDelay ) ) ++ { ++ KaxCodecDelay &codecdelay = *(KaxCodecDelay*)l; ++ tk->i_codec_delay = uint64_t( codecdelay ) / 1000; ++ msg_Dbg( &sys.demuxer, "| | | + Track Codec Delay =%"PRIu64, ++ tk->i_codec_delay ); ++ } ++ else if( MKV_IS_ID( l, KaxSeekPreRoll ) ) ++ { ++ KaxSeekPreRoll &spr = *(KaxSeekPreRoll*)l; ++ tk->i_seek_preroll = uint64_t(spr) / 1000; ++ msg_Dbg( &sys.demuxer, "| | | + Track Seek Preroll =%"PRIu64, tk->i_seek_preroll ); ++ } ++#endif + else if( MKV_IS_ID( l, KaxContentEncodings ) ) + { + EbmlMaster *cencs = static_cast<EbmlMaster*>(l); +@@ -1477,6 +1493,26 @@ int32_t matroska_segment_c::TrackInit( mkv_track_t * p_tk ) + p_tk->fmt.i_codec = VLC_CODEC_VORBIS; + fill_extra_data( p_tk, 0 ); + } ++ else if( !strncmp( p_tk->psz_codec, "A_OPUS", 6 ) ) ++ { ++ p_tk->fmt.i_codec = VLC_CODEC_OPUS; ++ if( !p_tk->fmt.audio.i_rate ) ++ { ++ msg_Err( &sys.demuxer,"No sampling rate, defaulting to 48kHz"); ++ p_tk->fmt.audio.i_rate = 48000; ++ } ++ const uint8_t tags[16] = {'O','p','u','s','T','a','g','s', ++ 0, 0, 0, 0, 0, 0, 0, 0}; ++ unsigned ps[2] = { p_tk->i_extra_data, 16 }; ++ const void *pkt[2] = { (const void *)p_tk->p_extra_data, ++ (const void *) tags }; ++ ++ if( xiph_PackHeaders( &p_tk->fmt.i_extra, ++ &p_tk->fmt.p_extra, ++ ps, pkt, 2 ) ) ++ msg_Err( &sys.demuxer, "Couldn't pack OPUS headers"); ++ ++ } + else if( !strncmp( p_tk->psz_codec, "A_AAC/MPEG2/", strlen( "A_AAC/MPEG2/" ) ) || + !strncmp( p_tk->psz_codec, "A_AAC/MPEG4/", strlen( "A_AAC/MPEG4/" ) ) ) + { +diff --git a/modules/demux/mkv/mkv.cpp b/modules/demux/mkv/mkv.cpp +index 6398409..7d42d83 100644 +--- a/modules/demux/mkv/mkv.cpp ++++ b/modules/demux/mkv/mkv.cpp +@@ -499,10 +499,8 @@ void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock + msg_Err( p_demux, "unknown track number" ); + return; + } +- if( i_pts + i_duration < p_sys->i_start_pts && tk->fmt.i_cat == AUDIO_ES ) +- { +- return; /* discard audio packets that shouldn't be rendered */ +- } ++ ++ i_pts -= tk->i_codec_delay; + + if ( tk->fmt.i_cat != NAV_ES ) + { +@@ -592,9 +590,10 @@ void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock + { + memcpy( p_block->p_buffer, tk->p_compression_data->GetBuffer(), tk->p_compression_data->GetSize() ); + } +- +- if( tk->fmt.i_codec == VLC_CODEC_COOK || +- tk->fmt.i_codec == VLC_CODEC_ATRAC3 ) ++ switch( tk->fmt.i_codec ) ++ { ++ case VLC_CODEC_COOK: ++ case VLC_CODEC_ATRAC3: + { + handle_real_audio(p_demux, tk, p_block, i_pts); + block_Release(p_block); +@@ -602,6 +601,27 @@ void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock + i_pts + ( mtime_t )( tk->i_default_duration / 1000 ): + VLC_TS_INVALID; + continue; ++ } ++ case VLC_CODEC_SPU: ++ if( strcmp( tk->psz_codec, "S_VOBSUB" ) ) ++ p_block->i_length = i_duration * tk-> f_timecodescale * ++ (double) p_segment->i_timescale / 1000.0; ++ break; ++ case VLC_CODEC_OPUS: ++ if( i_duration > 0 ) ++ { ++ mtime_t i_length = i_duration * tk-> f_timecodescale * ++ (double) p_segment->i_timescale / 1000.0; ++ p_block->i_nb_samples = i_length * tk->fmt.audio.i_rate ++ / CLOCK_FREQ; ++ break; ++ } ++ else if( i_duration < 0 ) ++ { ++ /* Opus uses p_block->i_length to handle discard padding */ ++ p_block->i_length = -1 * i_duration * tk->fmt.audio.i_rate ++ / CLOCK_FREQ; ++ } + } + + if ( tk->fmt.i_cat == NAV_ES ) +@@ -643,11 +663,6 @@ void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock + #if 0 + msg_Dbg( p_demux, "block i_dts: %"PRId64" / i_pts: %"PRId64, p_block->i_dts, p_block->i_pts); + #endif +- if( strcmp( tk->psz_codec, "S_VOBSUB" ) ) +- { +- p_block->i_length = i_duration * tk-> f_timecodescale * (double) p_segment->i_timescale / 1000.0; +- } +- + /* FIXME remove when VLC_TS_INVALID work is done */ + if( i == 0 || p_block->i_dts > VLC_TS_INVALID ) + p_block->i_dts += VLC_TS_0; +diff --git a/modules/demux/mkv/mkv.hpp b/modules/demux/mkv/mkv.hpp +index efc88b3..7cae3e7 100644 +--- a/modules/demux/mkv/mkv.hpp ++++ b/modules/demux/mkv/mkv.hpp +@@ -188,8 +188,6 @@ class PrivateTrackData + + struct mkv_track_t + { +-// ~mkv_track_t(); +- + bool b_default; + bool b_enabled; + bool b_forced; +@@ -237,6 +235,10 @@ struct mkv_track_t + uint32_t i_encoding_scope; + KaxContentCompSettings *p_compression_data; + ++ /* Matroska 4 new elements used by Opus */ ++ mtime_t i_seek_preroll; ++ mtime_t i_codec_delay; ++ + }; + + struct mkv_index_t diff --git a/helpers/make-vlc b/helpers/make-vlc new file mode 100644 index 0000000000000000000000000000000000000000..cb155a9d97c4b999d27f82fcda50656d41da6b41 --- /dev/null +++ b/helpers/make-vlc @@ -0,0 +1,29 @@ +#!/bin/sh +# +# Copyright (C) 2015 Santiago RodrÃguez <santi@trisquel.info> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# + +VERSION=1 + +. ./config + +#Enable OPUS support in mkv container +patch -p1 < $DATA/46fe18b280ed5825fd701edeedb2f5c24de001a2_without_xiph.patch + +changelog "Added opus support to mkv container" + +compile