Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • videolan/vlc
  • chouquette/vlc
  • bakiewicz.marek122/vlc
  • devnexen/vlc
  • rohanrajpal/vlc
  • blurrrb/vlc
  • gsoc/gsoc2019/darkapex/vlc
  • b1ue/vlc
  • fkuehne/vlc
  • magsoft/vlc
  • chub/vlc
  • cramiro9/vlc
  • robUx4/vlc
  • rom1v/vlc
  • akshayaky/vlc
  • tmk907/vlc
  • akymaster/vlc
  • govind.sharma/vlc
  • psilokos/vlc
  • xjbeta/vlc
  • jahan/vlc
  • 1480c1/vlc
  • amanchande/vlc
  • aaqib/vlc
  • rist/vlc
  • apol/vlc
  • mindfreeze/vlc
  • alexandre-janniaux/vlc
  • sandsmark/vlc
  • jagannatharjun/vlc
  • gsoc/gsoc2020/matiaslgonzalez/vlc
  • gsoc/gsoc2020/jagannatharjun/vlc
  • mstorsjo/vlc
  • gsoc/gsoc2020/vedenta/vlc
  • gsoc/gsoc2020/arnav-ishaan/vlc
  • gsoc/gsoc2020/andreduong/vlc
  • fuzun/vlc
  • gsoc/gsoc2020/vatsin/vlc
  • gsoc/gsoc2020/sagid/vlc
  • yaron/vlc
  • Phoenix/vlc
  • Garf/vlc
  • ePiratWorkarounds/vlc
  • tguillem/vlc
  • jnqnfe/vlc
  • mdc/vlc
  • Vedaa/vlc
  • rasa/vlc
  • quink/vlc
  • yealo/vlc
  • aleksey_ak/vlc
  • ePirat/vlc
  • ilya.yanok/vlc
  • asenat/vlc
  • m/vlc
  • bunjee/vlc
  • BLumia/vlc
  • sagudev/vlc
  • hamedmonji30/vlc
  • nullgemm/vlc
  • DivyamAhuja/vlc
  • thesamesam/vlc
  • dag7/vlc
  • snehil101/vlc
  • haasn/vlc
  • jbk/vlc
  • ValZapod/vlc
  • mfkl/vlc
  • WangChuan/vlc
  • core1024/vlc
  • GhostVaibhav/vlc
  • dfuhrmann/vlc
  • davide.prade/vlc
  • tmatth/vlc
  • Courmisch/vlc
  • zouya/vlc
  • hpi/vlc
  • EwoutH/vlc
  • aleung27/vlc
  • hengwu0/vlc
  • saladin/vlc
  • ashuio/vlc
  • richselwood/vlc
  • verma16Ayush/vlc
  • chemicalflash/vlc
  • PoignardAzur/vlc
  • huangjieNT/vlc
  • Blake-Haydon/vlc
  • AnuthaDev/vlc
  • gsoc/gsoc2021/mpd/vlc
  • nicolas_lequec/vlc
  • sambassaly/vlc
  • thresh/vlc
  • bonniegong/vlc
  • myaashish/vlc
  • stavros.vagionitis/vlc
  • ileoo/vlc
  • louis-santucci/vlc
  • cchristiansen/vlc
  • sabyasachi07/vlc
  • AbduAmeen/vlc
  • ashishb0410/vlc
  • urbanhusky/vlc
  • davidepietrasanta/vlc
  • riksleutelstad/vlc
  • jeremyVignelles/vlc
  • komh/vlc
  • iamjithinjohn/vlc
  • JohannesKauffmann/vlc2
  • kunglao/vlc
  • natzberg/vlc
  • jill/vlc
  • cwendling/vlc
  • adufou/vlc
  • ErwanAirone/vlc
  • HasinduDilshan10/vlc
  • vagrantc/vlc
  • rafiv/macos-bigsur-icon
  • Aymeriic/vlc
  • saranshg20/vlc
  • metzlove24/vlc
  • linkfanel/vlc
  • Ds886/vlc
  • metehan-arslan/vlc
  • Skantes/vlc
  • kgsandundananjaya96/vlc
  • mitchcapper/vlc
  • advaitgupta/vlc
  • StefanBruens/vlc
  • ratajs/vlc
  • T.M.F.B.3761/vlc
  • m222059/vlc
  • casemerrick/vlc
  • joshuaword2alt/vlc
  • sjwaddy/vlc
  • dima/vlc
  • Ybalrid/vlc
  • umxprime/vlc
  • eschmidt/vlc
  • vannieuwenhuysenmichelle/vlc
  • badcf00d/vlc
  • wesinator/vlc
  • louis/vlc
  • xqq/vlc
  • EmperorYP7/vlc
  • NicoLiam/vlc
  • loveleen/vlc
  • rofferom/vlc
  • rbultje/vlc
  • TheUnamed/vlc
  • pratiksharma341/vlc
  • Saurab17/vlc
  • purist.coder/vlc
  • Shuicheng/vlc
  • mdrrubel292/vlc
  • silverbleu00/vlc
  • metif12/vlc
  • asher-m/vlc
  • jeffk/vlc
  • Brandonbr1/vlc
  • beautyyuyanli/vlc
  • rego21/vlc
  • muyangren907/vlc
  • collectionbylawrencejason/vlc
  • evelez/vlc
  • GSMgeeth/vlc
  • Oneric/vlc
  • TJ5/vlc
  • XuanTung95/vlc
  • darrenjenny21/vlc
  • Trenly/vlc
  • RockyTDR/vlc
  • mjakubowski/vlc
  • caprica/vlc
  • ForteFrankie/vlc
  • seannamiller19/vlc
  • junlon2006/vlc
  • kiwiren6666/vlc
  • iuseiphonexs/vlc
  • fenngtun/vlc
  • Rajdutt999/vlc
  • typx/vlc
  • leon.vitanos/vlc
  • robertogarci0938/vlc
  • gsoc/gsoc2022/luc65r/vlc-mpd
  • skeller/vlc
  • MCJack123/vlc
  • luc65r/vlc-mpd
  • popov895/vlc
  • claucambra/vlc
  • brad/vlc
  • matthewmurua88/vlc
  • Tomas8874/vlc
  • philenotfound/vlc
  • makita-do3/vlc
  • LZXCorp/vlc
  • mar0x/vlc
  • senojetkennedy0102/vlc
  • shaneb243/vlc
  • ahmadbader/vlc
  • rajduttcse26/vlc-audio-filters
  • Juniorzito8415/vlc
  • achernyakov/vlc
  • lucasjetgroup/vlc
  • pupdoggy666/vlc
  • gmde9363/vlc
  • alexnwayne/vlc
  • bahareebrahimi781/vlc
  • hamad633666/vlc
  • umghof3112/vlc
  • joe0199771874/vlc
  • Octocats66666666/vlc
  • jjm_223/vlc
  • btech10110.19/vlc
  • sunnykfc028/vlc-audio-filters
  • loic/vlc
  • nguyenminhducmx1/vlc
  • JanekKrueger/vlc
  • bstubbington2/vlc
  • rcombs/vlc
  • Ordissimo/vlc
  • king7532/vlc
  • noobsauce101/vlc
  • schong0525/vlc
  • myQwil/vlc
  • apisbg91/vlc
  • geeboy0101017/vlc
  • kim.faughey/vlc
  • nurupo/vlc
  • yyusea/vlc
  • 0711235879.khco/vlc
  • ialo/vlc
  • iloveyeye2/vlc
  • gdtdftdqtd/vlc
  • leandroconsiglio/vlc
  • AndyHTML2012/vlc
  • ncz/vlc
  • lucenticus/vlc
  • knr1931/vlc
  • kjoonlee/vlc
  • chandrakant100/vlc-qt
  • johge42/vlc
  • polter/vlc
  • hexchain/vlc
  • Tushwrld/vlc
  • mztea928/vlc
  • jbelloncastro/vlc
  • alvinhochun/vlc
  • ghostpiratecrow/vlc
  • ujjwaltwitx/vlc
  • alexsonarin06/vlc
  • adrianbon76/vlc
  • altsod/vlc
  • damien.lucas44/vlc
  • dmytrivtaisa/vlc
  • utk202/vlc
  • aaxhrj/vlc
  • thomas.hermes/vlc
  • structurenewworldorder/vlc
  • slomo/vlc
  • wantlamy/vlc
  • musc.o3cminc/vlc
  • thebarshablog/vlc
  • kerrick/vlc
  • kratos142518/vlc
  • leogps/vlc
  • vacantron/vlc
  • luna_koly/vlc
  • Ratio2/vlc
  • anuoshemohammad/vlc
  • apsun/vlc
  • aaa1115910/vlc
  • alimotmoyo/vlc
  • Ambossmann/vlc
  • Sam-LearnsToCode/vlc
  • Chilledheart/vlc
  • Labnann/vlc
  • ktcoooot1/vlc
  • mohit-marathe/vlc
  • johnddx/vlc
  • manstabuk/vlc
  • Omar-ahmed314/vlc
  • vineethkm/vlc
  • 9Enemi86/vlc
  • radoslav.m.panteleev/vlc
  • ashishami2002/vlc
  • Corbax/vlc
  • firnasahmed/vlc
  • pelayarmalam4/vlc
  • c0ff330k/vlc
  • shikhindahikar/vlc
  • l342723951/vlc
  • christianschwandner/vlc
  • douniwan5788/vlc
  • 7damian7/vlc
  • ferdnyc/vlc
  • f.ales1/vlc
  • pandagby/vlc
  • BaaBaa/vlc
  • jewe37/vlc
  • w00drow/vlc
  • russelltg/vlc
  • ironicallygod/vlc
  • soumyaDghosh/vlc
  • linzihao1999/vlc
  • deyayush6/vlc
  • mibi88/vlc
  • newabdallah10/vlc
  • jhorbincolombia/vlc
  • rimvihaqueshupto/vlc
  • andrewkhon98/vlc
  • fab78/vlc
  • lapaz17/vlc
  • amanna13/vlc
  • mdakram28/vlc
  • 07jw1980/vlc
  • sohamgupta/vlc
  • Eson-Jia1/vlc
  • Sumou/vlc
  • vikram-kangotra/vlc
  • chalice191/vlc
  • olivercalder/vlc
  • aaasg4001/vlc
  • zipdox/vlc
  • kwizart/vlc
  • Dragon-S/vlc
  • jdemeule/vlc
  • gabriel_lt/vlc
  • locutusofborg/vlc
  • sammirata/vlc-librist
  • another/vlc
  • Benjamin_Loison/vlc
  • ahmedmoselhi/vlc
  • petergaal/vlc
  • huynhsontung/vlc
  • dariusmihut/vlc
  • tvermaashutosh/vlc
  • buti/vlc
  • Niram7777/vlc
  • rohan-here/vlc
  • balaji-sivasakthi/vlc
  • rlindner81/vlc
  • Kakadus/vlc
  • djain/vlc
  • ABBurmeister/vlc
  • craighuggins/vlc
  • orbea/vlc
  • maxos/vlc
  • aakarshmj/vlc
  • kblaschke/vlc
  • ankitm/vlc
  • advait-0/vlc
  • mohak2003/vlc
  • yselkowitz/vlc
  • AZM999/vlc-azm
  • andrey.turkin/vlc
  • Disha-Baghel/vlc
  • nowrep/vlc
  • Apeng/vlc
  • Choucroute_melba/vlc
  • autra/vlc
  • eclipseo/vlc
  • fhuber/vlc
  • olafhering/vlc
  • sdasda7777/vlc
  • 1div0/vlc
  • skosnits/vlc-extended-playlist-support
  • dnicolson/vlc
  • Timshel/vlc
  • octopols/vlc
  • MangalK/vlc
  • nima64/vlc
  • misawai/vlc
  • Alexander-Wilms/vlc
  • Maxime2/vlc-fork-for-visualizer
  • ww/vlc
  • jeske/vlc
  • sgross-emlix/vlc
  • morenonatural/vlc
  • freakingLovesVLC/vlc
  • borisgolovnev/vlc
  • mpromonet/vlc
  • diogo.simao-marques/vlc
  • masstock/vlc
  • pratikpatel8982/vlc
  • hugok79/vlc
  • longervision/vlc
  • abhiudaysurya/vlc
  • rishabhgarg/vlc
  • tumic/vlc
  • cart/vlc
  • shubham442/vlc
  • Aditya692005/vlc
  • sammirata/vlc4
  • syrykh/vlc
  • Vvorcun/macos-new-icon
  • AyaanshC/vlc
  • nasso/vlc
  • Quark/vlc
  • sebastinas/vlc
  • rhstone/vlc
  • talregev/vlc
  • Managor/vlc
403 results
Show changes
Commits on Source (7)
......@@ -1043,11 +1043,13 @@ static int SessionsSetup( demux_t *p_demux )
unsigned char *p_extra;
tk->fmt.i_codec = VLC_CODEC_OPUS;
OpusHeader header;
opus_header_init(&header);
// "The RTP clock rate in "a=rtpmap" MUST be 48000 and the number of channels MUST be 2."
// See: https://datatracker.ietf.org/doc/html/draft-ietf-payload-rtp-opus-11#section-7
opus_prepare_header( 2, 48000, &header );
if( opus_write_header( &p_extra, &i_extra, &header, NULL ) )
return VLC_ENOMEM;
opus_header_clean(&header);
tk->fmt.i_extra = i_extra;
tk->fmt.p_extra = p_extra;
}
......
......@@ -38,6 +38,9 @@
#include <ogg/ogg.h>
#include <opus.h>
#include <opus_multistream.h>
#ifdef OPUS_HAVE_OPUS_PROJECTION_H
# include <opus_projection.h> /* from 1.3.0 */
#endif
#include "opus_header.h"
......@@ -89,6 +92,9 @@ struct decoder_sys_t
*/
OpusHeader header;
OpusMSDecoder *p_st;
#ifdef OPUS_HAVE_OPUS_PROJECTION_H
OpusProjectionDecoder *p_pr;
#endif
/*
* Common properties
......@@ -162,6 +168,104 @@ static int ProcessInitialHeader ( decoder_t *, ogg_packet * );
static block_t *ProcessPacket( decoder_t *, ogg_packet *, block_t * );
static block_t *DecodePacket( decoder_t *, ogg_packet *, int, vlc_tick_t );
/*****************************************************************************
* Implementation Wrappers
*****************************************************************************/
static void DecoderDestroy( decoder_sys_t *p_sys )
{
#ifdef OPUS_HAVE_OPUS_PROJECTION_H
if( p_sys->p_pr )
{
opus_projection_decoder_destroy( p_sys->p_pr );
p_sys->p_pr = NULL;
}
else
#endif
if( p_sys->p_st )
{
opus_multistream_decoder_destroy( p_sys->p_st );
p_sys->p_st = NULL;
}
}
#ifdef OPUS_SET_GAIN
static int SetDecoderGain( decoder_sys_t *p_sys, int gain )
{
# ifdef OPUS_HAVE_OPUS_PROJECTION_H
if( p_sys->p_pr )
{
if( opus_projection_decoder_ctl(
p_sys->p_pr, OPUS_SET_GAIN(gain) ) != OPUS_OK )
return VLC_EGENERIC;
}
else
# endif
{
if( opus_multistream_decoder_ctl(
p_sys->p_st, OPUS_SET_GAIN(gain) ) != OPUS_OK )
return VLC_EGENERIC;
}
return VLC_SUCCESS;
}
#endif
static int DecoderDecodeFloat( decoder_sys_t *p_sys, const ogg_packet *p_oggpacket,
int spp, block_t *out )
{
#ifdef OPUS_HAVE_OPUS_PROJECTION_H
if( p_sys->p_pr )
return opus_projection_decode_float(p_sys->p_pr, p_oggpacket->packet,
p_oggpacket->bytes,
(float *)out->p_buffer, spp, 0);
else
#endif
return opus_multistream_decode_float(p_sys->p_st, p_oggpacket->packet,
p_oggpacket->bytes,
(float *)out->p_buffer, spp, 0);
}
static int DecoderCreate( decoder_sys_t *p_sys )
{
int err;
const OpusHeader *p_header = &p_sys->header;
#ifdef OPUS_HAVE_OPUS_PROJECTION_H
if( p_header->channel_mapping == 3 )
{
p_sys->p_pr = opus_projection_decoder_create( 48000, p_header->channels,
p_header->nb_streams, p_header->nb_coupled,
p_header->dmatrix, p_header->dmatrix_size, &err );
}
else
#endif
{
const unsigned char* p_stream_map = p_header->stream_map;
unsigned char new_stream_map[8];
if ( p_header->channel_mapping <= 1 )
{
if( p_header->channels > 2 )
{
static const uint32_t *pi_ch[6] = { pi_3channels_in, pi_4channels_in,
pi_5channels_in, pi_6channels_in,
pi_7channels_in, pi_8channels_in };
uint8_t pi_chan_table[AOUT_CHAN_MAX];
aout_CheckChannelReorder( pi_ch[p_header->channels-3], NULL,
pi_channels_maps[p_header->channels],
pi_chan_table );
for( int i=0;i<p_header->channels;i++ )
new_stream_map[pi_chan_table[i]] = p_header->stream_map[i];
p_stream_map = new_stream_map;
}
}
p_sys->p_st = opus_multistream_decoder_create( 48000, p_header->channels,
p_header->nb_streams, p_header->nb_coupled,
p_stream_map, &err );
}
return err == OPUS_OK ? VLC_SUCCESS : VLC_EGENERIC;
}
/*****************************************************************************
* OpenDecoder: probe the decoder and return score
......@@ -178,6 +282,7 @@ static int OpenDecoder( vlc_object_t *p_this )
if( ( p_dec->p_sys = p_sys = malloc(sizeof(decoder_sys_t)) ) == NULL )
return VLC_ENOMEM;
p_dec->p_sys->b_has_headers = false;
opus_header_init(&p_sys->header);
date_Set( &p_sys->end_date, 0 );
......@@ -189,6 +294,9 @@ static int OpenDecoder( vlc_object_t *p_this )
p_dec->pf_flush = Flush;
p_sys->p_st = NULL;
#ifdef OPUS_HAVE_OPUS_PROJECTION_H
p_sys->p_pr = NULL;
#endif
return VLC_SUCCESS;
}
......@@ -252,6 +360,7 @@ static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
*****************************************************************************/
static int ProcessHeaders( decoder_t *p_dec )
{
decoder_sys_t *p_sys = p_dec->p_sys;
ogg_packet oggpacket;
unsigned pi_size[XIPH_MAX_HEADER_COUNT];
......@@ -259,52 +368,63 @@ static int ProcessHeaders( decoder_t *p_dec )
unsigned i_count;
int i_extra = p_dec->fmt_in.i_extra;
uint8_t *p_extra = p_dec->fmt_in.p_extra;
const uint8_t *p_extra = p_dec->fmt_in.p_extra;
uint8_t *p_alloc = NULL;
/* Xiph headers as extradata */
if( i_extra > 21 && !memcmp( &p_extra[2], "OpusHead", 8 ) )
{
if( xiph_SplitHeaders( pi_size, pp_data, &i_count,
i_extra, p_extra ) || i_count < 2 )
{
/* Borked Xiph headers */
free( p_alloc );
return VLC_EGENERIC;
}
oggpacket.bytes = pi_size[0];
oggpacket.packet = (unsigned char *) pp_data[0];
}
/* If we have no header (e.g. from RTP), make one. */
bool b_dummy_header = false;
if( !i_extra ||
(i_extra > 10 && memcmp( &p_extra[2], "OpusHead", 8 )) ) /* Borked muxers */
else if( i_extra < 19 || memcmp( p_extra, "OpusHead", 8 ) )
{
OpusHeader header;
opus_prepare_header( p_dec->fmt_in.audio.i_channels,
p_dec->fmt_in.audio.i_rate, &header );
if( opus_write_header( &p_extra, &i_extra, &header,
opus_get_version_string() ) )
opus_header_init(&header);
opus_prepare_header( p_dec->fmt_in.audio.i_channels ? p_dec->fmt_in.audio.i_channels : 2,
p_dec->fmt_in.audio.i_rate ? p_dec->fmt_in.audio.i_rate : 48000,
&header );
int ret = opus_write_header( &p_alloc, &i_extra, &header,
opus_get_version_string() );
opus_header_clean(&header);
if(ret != 0 || i_extra < 21)
{
free( p_alloc );
return VLC_ENOMEM;
b_dummy_header = true;
}
if( xiph_SplitHeaders( pi_size, pp_data, &i_count,
i_extra, p_extra ) )
{
if( b_dummy_header )
free( p_extra );
return VLC_EGENERIC;
}
oggpacket.bytes = p_alloc[1]; /* Xiph header is type8/size8 */
oggpacket.packet = (unsigned char *) p_alloc + 2; /* Point directly to opus header start */
}
if( i_count < 2 )
else /* raw header in extradata */
{
if( b_dummy_header )
free( p_extra );
return VLC_EGENERIC;
oggpacket.bytes = i_extra;
oggpacket.packet = (unsigned char *) p_extra;
}
/* Take care of the initial Opus header */
oggpacket.granulepos = -1;
oggpacket.e_o_s = 0;
oggpacket.packetno = 0;
/* Take care of the initial Opus header */
oggpacket.b_o_s = 1; /* yes this actually is a b_o_s packet :) */
oggpacket.bytes = pi_size[0];
oggpacket.packet = (void *)pp_data[0];
int ret = ProcessInitialHeader( p_dec, &oggpacket );
if (ret != VLC_SUCCESS)
{
msg_Err( p_dec, "initial Opus header is corrupted" );
opus_header_clean( &p_sys->header );
opus_header_init( &p_sys->header );
}
if( b_dummy_header )
free( p_extra );
free( p_alloc );
return ret;
}
......@@ -314,10 +434,7 @@ static int ProcessHeaders( decoder_t *p_dec )
*****************************************************************************/
static int ProcessInitialHeader( decoder_t *p_dec, ogg_packet *p_oggpacket )
{
int err;
unsigned char new_stream_map[8];
decoder_sys_t *p_sys = p_dec->p_sys;
OpusHeader *p_header = &p_sys->header;
if( !opus_header_parse((unsigned char *)p_oggpacket->packet,p_oggpacket->bytes,p_header) )
......@@ -328,48 +445,52 @@ static int ProcessInitialHeader( decoder_t *p_dec, ogg_packet *p_oggpacket )
msg_Dbg( p_dec, "Opus audio with %d channels", p_header->channels);
if((p_header->channels>2 && p_header->channel_mapping==0) ||
p_header->channels>8 ||
p_header->channel_mapping>1)
(p_header->channels>8 && p_header->channel_mapping==1) ||
(p_header->channels>18 && p_header->channel_mapping==2) ||
(p_header->channels>18 && p_header->channel_mapping==3))
{
msg_Err( p_dec, "Unsupported channel mapping" );
return VLC_EGENERIC;
}
if (p_header->channel_mapping >= 2)
{
int i_order = floor(sqrt(p_header->channels));
int i_nondiegetic = p_header->channels - i_order * i_order;
msg_Dbg( p_dec, "Opus Ambisonic audio order=%d channels=%d+%d",
i_order, p_header->channels - i_nondiegetic, i_nondiegetic);
if (i_nondiegetic != 0 && i_nondiegetic != 2)
{
msg_Err( p_dec, "Unsupported ambisonic channel mapping" );
return VLC_EGENERIC;
}
}
/* Setup the format */
p_dec->fmt_out.audio.i_physical_channels =
pi_channels_maps[p_header->channels];
p_dec->fmt_out.audio.i_channels = p_header->channels;
p_dec->fmt_out.audio.i_rate = 48000;
if( p_header->channels>2 )
if (p_header->channel_mapping <= 1)
{
static const uint32_t *pi_ch[6] = { pi_3channels_in, pi_4channels_in,
pi_5channels_in, pi_6channels_in,
pi_7channels_in, pi_8channels_in };
uint8_t pi_chan_table[AOUT_CHAN_MAX];
aout_CheckChannelReorder( pi_ch[p_header->channels-3], NULL,
p_dec->fmt_out.audio.i_physical_channels,
pi_chan_table );
for(int i=0;i<p_header->channels;i++)
new_stream_map[pi_chan_table[i]]=p_header->stream_map[i];
p_dec->fmt_out.audio.i_physical_channels =
pi_channels_maps[p_header->channels];
}
else //p_header->channel_mapping >= 2
{
p_dec->fmt_out.audio.channel_type = AUDIO_CHANNEL_TYPE_AMBISONICS;
}
/* Opus decoder init */
p_sys->p_st = opus_multistream_decoder_create( 48000, p_header->channels,
p_header->nb_streams, p_header->nb_coupled,
p_header->channels>2?new_stream_map:p_header->stream_map,
&err );
if( !p_sys->p_st || err!=OPUS_OK )
if( DecoderCreate( p_sys ) != VLC_SUCCESS )
{
msg_Err( p_dec, "decoder initialization failed" );
return VLC_EGENERIC;
}
#ifdef OPUS_SET_GAIN
if( opus_multistream_decoder_ctl( p_sys->p_st,OPUS_SET_GAIN(p_header->gain) ) != OPUS_OK )
if( SetDecoderGain( p_sys, p_header->gain ) != VLC_SUCCESS )
{
msg_Err( p_dec, "OPUS_SET_GAIN failed" );
opus_multistream_decoder_destroy( p_sys->p_st );
DecoderDestroy( p_sys );
return VLC_EGENERIC;
}
#endif
......@@ -470,8 +591,7 @@ static block_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
return NULL;
}
spp=opus_multistream_decode_float(p_sys->p_st, p_oggpacket->packet,
p_oggpacket->bytes, (float *)p_aout_buffer->p_buffer, spp, 0);
spp = DecoderDecodeFloat( p_sys, p_oggpacket, spp, p_aout_buffer );
if( spp < 0 || i_nb_samples <= 0 || i_end_trim >= i_nb_samples)
{
block_Release(p_aout_buffer);
......@@ -516,8 +636,9 @@ static void CloseDecoder( vlc_object_t *p_this )
decoder_t * p_dec = (decoder_t *)p_this;
decoder_sys_t *p_sys = p_dec->p_sys;
if( p_sys->p_st ) opus_multistream_decoder_destroy(p_sys->p_st);
DecoderDestroy( p_sys );
opus_header_clean( &p_sys->header );
free( p_sys );
}
......@@ -656,6 +777,7 @@ static int OpenEncoder(vlc_object_t *p_this)
enc->fmt_out.audio.i_channels = enc->fmt_in.audio.i_channels;
OpusHeader header;
opus_header_init(&header);
opus_prepare_header(enc->fmt_out.audio.i_channels,
enc->fmt_out.audio.i_rate, &header);
......@@ -730,9 +852,12 @@ static int OpenEncoder(vlc_object_t *p_this)
sys->padding = NULL;
}
opus_header_clean(&header);
return status;
error:
opus_header_clean(&header);
if (sys->enc)
opus_multistream_encoder_destroy(sys->enc);
free(sys->buffer);
......
......@@ -179,7 +179,16 @@ int opus_header_parse(const unsigned char *packet, int len, OpusHeader *h)
return 0;
h->channel_mapping = ch;
if (h->channel_mapping != 0)
if(h->channel_mapping == 0)
{
if(h->channels>2)
return 0;
h->nb_streams = 1;
h->nb_coupled = h->channels>1;
h->stream_map[0]=0;
h->stream_map[1]=1;
}
else if(h->channel_mapping < 4)
{
if (!read_chars(&p, &ch, 1))
return 0;
......@@ -191,26 +200,43 @@ int opus_header_parse(const unsigned char *packet, int len, OpusHeader *h)
if (!read_chars(&p, &ch, 1))
return 0;
if (ch>h->nb_streams || (ch+h->nb_streams)>255)
if (ch > h->nb_streams)
return 0;
h->nb_coupled = ch;
/* Multi-stream support */
for (int i=0;i<h->channels;i++)
if(h->channel_mapping == 2)
{
if (h->nb_coupled + h->nb_streams > 255)
return 0;
for (int i=0;i<h->channels;i++)
{
if (!read_chars(&p, &h->stream_map[i], 1))
return 0;
if (h->stream_map[i]>(h->nb_streams+h->nb_coupled) && h->stream_map[i]!=255)
return 0;
}
}
else /* Decoding Matrix */
{
if (!read_chars(&p, &h->stream_map[i], 1))
if (h->nb_coupled + h->nb_streams > 255)
return 0;
int matrix_entries = h->channels * (h->nb_streams + h->nb_coupled);
int matrix_size = len - p.pos;
if(matrix_size < matrix_entries * 2)
return 0;
if (h->stream_map[i]>(h->nb_streams+h->nb_coupled) && h->stream_map[i]!=255)
h->dmatrix = malloc(matrix_size);
if(h->dmatrix == NULL)
return 0;
if(!read_chars(&p, h->dmatrix, matrix_size))
{
free(h->dmatrix);
return 0;
}
h->dmatrix_size = matrix_size;
}
} else {
if(h->channels>2)
return 0;
h->nb_streams = 1;
h->nb_coupled = h->channels>1;
h->stream_map[0]=0;
h->stream_map[1]=1;
}
/*For version 0/1 we know there won't be any more data
so reject any that have data past the end.*/
if ((h->version==0 || h->version==1) && p.pos != len)
......@@ -350,7 +376,7 @@ static int opus_header_to_packet(const OpusHeader *h, unsigned char *packet, int
if (!write_chars(&p, &ch, 1))
return 0;
if (h->channel_mapping != 0)
if (h->channel_mapping == 1)
{
ch = h->nb_streams;
if (!write_chars(&p, &ch, 1))
......@@ -421,3 +447,21 @@ int opus_write_header(uint8_t **p_extra, int *i_extra, OpusHeader *header, const
return 0;
}
void opus_header_init(OpusHeader *h)
{
h->version = 0;
h->channels = 0;
h->preskip = 3840; /* default is 80 ms */
h->input_sample_rate = 0; /* unknown */
h->gain = 0;
h->channel_mapping = 255; /* unknown */
h->nb_streams = 0;
h->nb_coupled = 0;
h->dmatrix_size = 0;
h->dmatrix = NULL;
}
void opus_header_clean(OpusHeader *h)
{
free(h->dmatrix);
}
......@@ -41,8 +41,12 @@ typedef struct {
int nb_streams;
int nb_coupled;
unsigned char stream_map[255];
size_t dmatrix_size;
unsigned char *dmatrix;
} OpusHeader;
void opus_header_init(OpusHeader *);
void opus_header_clean(OpusHeader *);
int opus_header_parse(const unsigned char *header, int len, OpusHeader *h);
void opus_prepare_header(unsigned channels, unsigned rate, OpusHeader *header);
int opus_write_header(uint8_t **p_extra, int *i_extra, OpusHeader *header, const char *vendor);
......
......@@ -850,6 +850,7 @@ static int vlc_ceil_log2( const unsigned int val )
static void OpusSetup(demux_t *demux, uint8_t *p, size_t len, es_format_t *p_fmt)
{
OpusHeader h;
opus_header_init(&h);
/* default mapping */
static const unsigned char map[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
......@@ -930,6 +931,7 @@ static void OpusSetup(demux_t *demux, uint8_t *p, size_t len, es_format_t *p_fmt
if (!channels) {
msg_Err(demux, "Opus channel configuration 0x%.2x not supported yet", p[1]);
opus_header_clean(&h);
return;
}
......@@ -952,10 +954,12 @@ static void OpusSetup(demux_t *demux, uint8_t *p, size_t len, es_format_t *p_fmt
p_fmt->audio.i_rate = 48000;
}
}
opus_header_clean(&h);
return;
explicit_config_too_short:
opus_header_clean(&h);
msg_Err(demux, "Opus descriptor too short");
}
......