opus: Update to upstream opusfile 0.8

Had missed it in the previous commit as the upstream website is outdated.

(cherry picked from commit c2310b41fa)
This commit is contained in:
Rémi Verschelde 2017-01-08 20:59:18 +01:00
parent d66740175e
commit af7fd899f4
5 changed files with 111 additions and 72 deletions

View file

@ -121,7 +121,7 @@ TODO.
## opus
- Upstream: https://opus-codec.org
- Version: 1.1.3 (opus) and 0.7 (opusfile)
- Version: 1.1.3 (opus) and 0.8 (opusfile)
- License: BSD-3-Clause
Files extracted from upstream source:

View file

@ -894,7 +894,7 @@ static void op_http_stream_init(OpusHTTPStream *_stream){
/*Close the connection and move it to the free list.
_stream: The stream containing the free list.
_conn: The connection to close.
_penxt: The linked-list pointer currently pointing to this connection.
_pnext: The linked-list pointer currently pointing to this connection.
_gracefully: Whether or not to shut down cleanly.*/
static void op_http_conn_close(OpusHTTPStream *_stream,OpusHTTPConn *_conn,
OpusHTTPConn **_pnext,int _gracefully){
@ -1517,10 +1517,17 @@ static long op_bio_retry_ctrl(BIO *_b,int _cmd,long _num,void *_ptr){
return ret;
}
# if OPENSSL_VERSION_NUMBER<0x10100000L
# define BIO_set_data(_b,_ptr) ((_b)->ptr=(_ptr))
# define BIO_set_init(_b,_init) ((_b)->init=(_init))
# endif
static int op_bio_retry_new(BIO *_b){
_b->init=1;
BIO_set_init(_b,1);
# if OPENSSL_VERSION_NUMBER<0x10100000L
_b->num=0;
_b->ptr=NULL;
# endif
BIO_set_data(_b,NULL);
return 1;
}
@ -1528,6 +1535,7 @@ static int op_bio_retry_free(BIO *_b){
return _b!=NULL;
}
# if OPENSSL_VERSION_NUMBER<0x10100000L
/*This is not const because OpenSSL doesn't allow it, even though it won't
write to it.*/
static BIO_METHOD op_bio_retry_method={
@ -1542,11 +1550,15 @@ static BIO_METHOD op_bio_retry_method={
op_bio_retry_free,
NULL
};
# endif
/*Establish a CONNECT tunnel and pipeline the start of the TLS handshake for
proxying https URL requests.*/
static int op_http_conn_establish_tunnel(OpusHTTPStream *_stream,
OpusHTTPConn *_conn,op_sock _fd,SSL *_ssl_conn,BIO *_ssl_bio){
# if OPENSSL_VERSION_NUMBER>=0x10100000L
BIO_METHOD *bio_retry_method;
# endif
BIO *retry_bio;
char *status_code;
char *next;
@ -1557,13 +1569,32 @@ static int op_http_conn_establish_tunnel(OpusHTTPStream *_stream,
ret=op_http_conn_write_fully(_conn,
_stream->proxy_connect.buf,_stream->proxy_connect.nbuf);
if(OP_UNLIKELY(ret<0))return ret;
# if OPENSSL_VERSION_NUMBER>=0x10100000L
bio_retry_method=BIO_meth_new(BIO_TYPE_NULL,"retry");
if(bio_retry_method==NULL)return OP_EFAULT;
BIO_meth_set_write(bio_retry_method,op_bio_retry_write);
BIO_meth_set_read(bio_retry_method,op_bio_retry_read);
BIO_meth_set_puts(bio_retry_method,op_bio_retry_puts);
BIO_meth_set_ctrl(bio_retry_method,op_bio_retry_ctrl);
BIO_meth_set_create(bio_retry_method,op_bio_retry_new);
BIO_meth_set_destroy(bio_retry_method,op_bio_retry_free);
retry_bio=BIO_new(bio_retry_method);
if(OP_UNLIKELY(retry_bio==NULL)){
BIO_meth_free(bio_retry_method);
return OP_EFAULT;
}
# else
retry_bio=BIO_new(&op_bio_retry_method);
if(OP_UNLIKELY(retry_bio==NULL))return OP_EFAULT;
# endif
SSL_set_bio(_ssl_conn,retry_bio,_ssl_bio);
SSL_set_connect_state(_ssl_conn);
/*This shouldn't succeed, since we can't read yet.*/
OP_ALWAYS_TRUE(SSL_connect(_ssl_conn)<0);
SSL_set_bio(_ssl_conn,_ssl_bio,_ssl_bio);
# if OPENSSL_VERSION_NUMBER>=0x10100000L
BIO_meth_free(bio_retry_method);
# endif
/*Only now do we disable write coalescing, to allow the CONNECT
request and the start of the TLS handshake to be combined.*/
op_sock_set_tcp_nodelay(_fd,1);
@ -2200,6 +2231,7 @@ static int op_http_stream_open(OpusHTTPStream *_stream,const char *_url,
/*Initialize the SSL library if necessary.*/
if(OP_URL_IS_SSL(&_stream->url)&&_stream->ssl_ctx==NULL){
SSL_CTX *ssl_ctx;
# if OPENSSL_VERSION_NUMBER<0x10100000L
# if !defined(OPENSSL_NO_LOCKING)
/*The documentation says SSL_library_init() is not reentrant.
We don't want to add our own depenencies on a threading library, and it
@ -2216,6 +2248,10 @@ static int op_http_stream_open(OpusHTTPStream *_stream,const char *_url,
OpenSSL_add_ssl_algorithms();
# if !defined(OPENSSL_NO_LOCKING)
CRYPTO_w_unlock(CRYPTO_LOCK_SSL);
# endif
# else
/*Finally, OpenSSL does this for us, but as penance, it can now fail.*/
if(!OPENSSL_init_ssl(0,NULL))return OP_EFAULT;
# endif
ssl_ctx=SSL_CTX_new(SSLv23_client_method());
if(ssl_ctx==NULL)return OP_EFAULT;
@ -2779,7 +2815,7 @@ static int op_http_conn_read_body(OpusHTTPStream *_stream,
Otherwise, we'd need a _pnext pointer if we needed to close the connection,
and re-opening it would re-organize the lists.*/
OP_ASSERT(_stream->lru_head==_conn);
/*We should have filterd out empty reads by this point.*/
/*We should have filtered out empty reads by this point.*/
OP_ASSERT(_buf_size>0);
pos=_conn->pos;
end_pos=_conn->end_pos;

View file

@ -199,17 +199,22 @@ static int opus_tags_parse_impl(OpusTags *_tags,
if(_tags->user_comments[ci]==NULL)return OP_EFAULT;
_tags->comment_lengths[ci]=(int)count;
_tags->comments=ci+1;
/*Needed by opus_tags_clear() if we fail before parsing the (optional)
binary metadata.*/
_tags->user_comments[ci+1]=NULL;
}
_data+=count;
len-=count;
}
if(len>0&&(_data[0]&1)){
if(len>(opus_uint32)INT_MAX)return OP_EFAULT;
if(_tags!=NULL){
_tags->user_comments[ncomments]=(char *)_ogg_malloc(len);
if(OP_UNLIKELY(_tags->user_comments[ncomments]==NULL))return OP_EFAULT;
memcpy(_tags->user_comments[ncomments],_data,len);
_tags->comment_lengths[ncomments]=(int)len;
}
}
return 0;
}
@ -306,7 +311,7 @@ int opus_tags_add_comment(OpusTags *_tags,const char *_comment){
if(OP_UNLIKELY(ret<0))return ret;
comment_len=(int)strlen(_comment);
comment=op_strdup_with_len(_comment,comment_len);
if(OP_UNLIKELY(_tags->user_comments[ncomments]==NULL))return OP_EFAULT;
if(OP_UNLIKELY(comment==NULL))return OP_EFAULT;
_tags->user_comments[ncomments]=comment;
_tags->comment_lengths[ncomments]=comment_len;
_tags->comments=ncomments+1;

View file

@ -1713,11 +1713,11 @@ int op_pcm_seek(OggOpusFile *_of,ogg_int64_t _pcm_offset) OP_ARG_NONNULL(1);
These downmix multichannel files to two channels, so they can always return
samples in the same format for every link in a chained file.
If the rest of your audio processing chain can handle floating point, those
routines should be preferred, as floating point output avoids introducing
clipping and other issues which might be avoided entirely if, e.g., you
scale down the volume at some other stage.
However, if you intend to direct consume 16-bit samples, the conversion in
If the rest of your audio processing chain can handle floating point, the
floating-point routines should be preferred, as they prevent clipping and
other issues which might be avoided entirely if, e.g., you scale down the
volume at some other stage.
However, if you intend to consume 16-bit samples directly, the conversion in
<tt>libopusfile</tt> provides noise-shaping dithering and, if compiled
against <tt>libopus</tt>&nbsp;1.1 or later, soft-clipping prevention.
@ -1770,26 +1770,35 @@ int op_pcm_seek(OggOpusFile *_of,ogg_int64_t _pcm_offset) OP_ARG_NONNULL(1);
#OP_DEC_FORMAT_FLOAT.
\param _li The index of the link from which this packet was decoded.
\return A non-negative value on success, or a negative value on error.
The error codes should be the same as those returned by
Any error codes should be the same as those returned by
opus_multistream_decode() or opus_multistream_decode_float().
Success codes are as follows:
\retval 0 Decoding was successful.
The application has filled the buffer with
exactly <code>\a _nsamples*\a
_nchannels</code> samples in the requested
format.
\retval #OP_DEC_USE_DEFAULT No decoding was done.
<tt>libopusfile</tt> should decode normally
instead.*/
<tt>libopusfile</tt> should do the decoding
by itself instead.*/
typedef int (*op_decode_cb_func)(void *_ctx,OpusMSDecoder *_decoder,void *_pcm,
const ogg_packet *_op,int _nsamples,int _nchannels,int _format,int _li);
/**Sets the packet decode callback function.
This is called once for each packet that needs to be decoded.
If set, this is called once for each packet that needs to be decoded.
This can be used by advanced applications to do additional processing on the
compressed or uncompressed data.
For example, an application might save the final entropy coder state for
debugging and testing purposes, or it might apply additional filters
before the downmixing, dithering, or soft-clipping performed by
<tt>libopusfile</tt>, so long as these filters do not introduce any
latency.
A call to this function is no guarantee that the audio will eventually be
delivered to the application.
Some or all of the data from the packet may be discarded (i.e., at the
beginning or end of a link, or after a seek), however the callback is
required to provide all of it.
<tt>libopusfile</tt> may discard some or all of the decoded audio data
(i.e., at the beginning or end of a link, or after a seek), however the
callback is still required to provide all of it.
\param _of The \c OggOpusFile on which to set the decode callback.
\param _decode_cb The callback function to call.
This may be <code>NULL</code> to disable calling the

View file

@ -505,6 +505,7 @@ static int op_fetch_headers_impl(OggOpusFile *_of,OpusHead *_head,
Everything else is fatal.*/
else if(ret!=OP_ENOTFORMAT)return ret;
}
/*TODO: Should a BOS page with no packets be an error?*/
}
/*Get the next page.
No need to clamp the boundary offset against _of->end, as all errors
@ -1823,14 +1824,11 @@ opus_int32 op_bitrate_instant(OggOpusFile *_of){
This handles the case where we're at a bitstream boundary and dumps the
decoding machine.
If the decoding machine is unloaded, it loads it.
It also keeps prev_packet_gp up to date (seek and read both use this; seek
uses a special hack with _readp).
It also keeps prev_packet_gp up to date (seek and read both use this).
Return: <0) Error, OP_HOLE (lost packet), or OP_EOF.
0) Need more data (only if _readp==0).
1) Got at least one audio data packet.*/
0) Got at least one audio data packet.*/
static int op_fetch_and_process_page(OggOpusFile *_of,
ogg_page *_og,opus_int64 _page_offset,
int _readp,int _spanp,int _ignore_holes){
ogg_page *_og,opus_int64 _page_offset,int _spanp,int _ignore_holes){
OggOpusLink *links;
ogg_uint32_t cur_serialno;
int seekable;
@ -1838,7 +1836,6 @@ static int op_fetch_and_process_page(OggOpusFile *_of,
int ret;
/*We shouldn't get here if we have unprocessed packets.*/
OP_ASSERT(_of->ready_state<OP_INITSET||_of->op_pos>=_of->op_count);
if(!_readp)return 0;
seekable=_of->seekable;
links=_of->links;
cur_link=seekable?_of->cur_link:0;
@ -1847,11 +1844,6 @@ static int op_fetch_and_process_page(OggOpusFile *_of,
for(;;){
ogg_page og;
OP_ASSERT(_of->ready_state>=OP_OPENED);
/*This loop is not strictly necessary, but there's no sense in doing the
extra checks of the larger loop for the common case in a multiplexed
bistream where the page is simply part of a different logical
bitstream.*/
do{
/*If we were given a page to use, use it.*/
if(_og!=NULL){
*&og=*_og;
@ -1861,22 +1853,18 @@ static int op_fetch_and_process_page(OggOpusFile *_of,
else _page_offset=op_get_next_page(_of,&og,_of->end);
/*EOF: Leave uninitialized.*/
if(_page_offset<0)return _page_offset<OP_FALSE?(int)_page_offset:OP_EOF;
if(OP_LIKELY(_of->ready_state>=OP_STREAMSET)){
if(cur_serialno!=(ogg_uint32_t)ogg_page_serialno(&og)){
if(OP_LIKELY(_of->ready_state>=OP_STREAMSET)
&&cur_serialno!=(ogg_uint32_t)ogg_page_serialno(&og)){
/*Two possibilities:
1) Another stream is multiplexed into this logical section, or*/
if(OP_LIKELY(!ogg_page_bos(&og)))continue;
/* 2) Our decoding just traversed a bitstream boundary.*/
if(!_spanp)return OP_EOF;
if(OP_LIKELY(_of->ready_state>=OP_INITSET))op_decode_clear(_of);
break;
}
}
/*Bitrate tracking: add the header's bytes here.
The body bytes are counted when we consume the packets.*/
_of->bytes_tracked+=og.header_len;
}
while(0);
else _of->bytes_tracked+=og.header_len;
/*Do we need to load a new machine before submitting the page?
This is different in the seekable and non-seekable cases.
In the seekable case, we already have all the header information loaded
@ -1934,10 +1922,12 @@ static int op_fetch_and_process_page(OggOpusFile *_of,
/*If we didn't get any packets out of op_find_initial_pcm_offset(),
keep going (this is possible if end-trimming trimmed them all).*/
if(_of->op_count<=0)continue;
/*Otherwise, we're done.*/
/*Otherwise, we're done.
TODO: This resets bytes_tracked, which misses the header bytes
already processed by op_find_initial_pcm_offset().*/
ret=op_make_decode_ready(_of);
if(OP_UNLIKELY(ret<0))return ret;
return 1;
return 0;
}
}
/*The buffered page is the data we want, and we're ready for it.
@ -2088,7 +2078,7 @@ static int op_fetch_and_process_page(OggOpusFile *_of,
_of->prev_page_offset=_page_offset;
_of->op_count=pi;
/*If end-trimming didn't trim all the packets, we're done.*/
if(OP_LIKELY(pi>0))return 1;
if(OP_LIKELY(pi>0))return 0;
}
}
}
@ -2106,7 +2096,7 @@ int op_raw_seek(OggOpusFile *_of,opus_int64 _pos){
_of->samples_tracked=0;
ret=op_seek_helper(_of,_pos);
if(OP_UNLIKELY(ret<0))return OP_EREAD;
ret=op_fetch_and_process_page(_of,NULL,-1,1,1,1);
ret=op_fetch_and_process_page(_of,NULL,-1,1,1);
/*If we hit EOF, op_fetch_and_process_page() leaves us uninitialized.
Instead, jump to the end.*/
if(ret==OP_EOF){
@ -2118,7 +2108,6 @@ int op_raw_seek(OggOpusFile *_of,opus_int64 _pos){
_of->cur_discard_count=0;
ret=0;
}
else if(ret>0)ret=0;
return ret;
}
@ -2506,8 +2495,8 @@ static int op_pcm_seek_page(OggOpusFile *_of,
/*Update prev_packet_gp to allow per-packet granule position assignment.*/
_of->prev_packet_gp=best_gp;
_of->prev_page_offset=best_start;
ret=op_fetch_and_process_page(_of,page_offset<0?NULL:&og,page_offset,1,0,1);
if(OP_UNLIKELY(ret<=0))return OP_EBADLINK;
ret=op_fetch_and_process_page(_of,page_offset<0?NULL:&og,page_offset,0,1);
if(OP_UNLIKELY(ret<0))return OP_EBADLINK;
/*Verify result.*/
if(OP_UNLIKELY(op_granpos_cmp(_of->prev_packet_gp,_target_gp)>0)){
return OP_EBADLINK;
@ -2589,8 +2578,8 @@ int op_pcm_seek(OggOpusFile *_of,ogg_int64_t _pcm_offset){
if(op_pos<op_count)break;
/*We skipped all the packets on this page.
Fetch another.*/
ret=op_fetch_and_process_page(_of,NULL,-1,1,0,1);
if(OP_UNLIKELY(ret<=0))return OP_EBADLINK;
ret=op_fetch_and_process_page(_of,NULL,-1,0,1);
if(OP_UNLIKELY(ret<0))return OP_EBADLINK;
}
OP_ALWAYS_TRUE(!op_granpos_diff(&diff,prev_packet_gp,pcm_start));
/*We skipped too far.
@ -2854,7 +2843,7 @@ static int op_read_native(OggOpusFile *_of,
}
}
/*Suck in another page.*/
ret=op_fetch_and_process_page(_of,NULL,-1,1,1,0);
ret=op_fetch_and_process_page(_of,NULL,-1,1,0);
if(OP_UNLIKELY(ret==OP_EOF)){
if(_li!=NULL)*_li=_of->cur_link;
return 0;