Browse Source

opus: Update to upstream opusfile 0.8

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

(cherry picked from commit c2310b41fa71ce94c2cc127c55b39b8ba07ab4c3)
Rémi Verschelde 8 years ago
parent
commit
af7fd899f4
5 changed files with 111 additions and 72 deletions
  1. 1 1
      thirdparty/README.md
  2. 44 8
      thirdparty/opus/http.c
  3. 10 5
      thirdparty/opus/info.c
  4. 21 12
      thirdparty/opus/opus/opusfile.h
  5. 35 46
      thirdparty/opus/opusfile.c

+ 1 - 1
thirdparty/README.md

@@ -121,7 +121,7 @@ TODO.
 ## opus
 ## opus
 
 
 - Upstream: https://opus-codec.org
 - 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
 - License: BSD-3-Clause
 
 
 Files extracted from upstream source:
 Files extracted from upstream source:

+ 44 - 8
thirdparty/opus/http.c

@@ -231,7 +231,7 @@ typedef SOCKET op_sock;
 #   define POLLRDBAND (0x0200)
 #   define POLLRDBAND (0x0200)
 /*There is data to read.*/
 /*There is data to read.*/
 #   define POLLIN     (POLLRDNORM|POLLRDBAND)
 #   define POLLIN     (POLLRDNORM|POLLRDBAND)
-/* There is urgent data to read.*/
+/*There is urgent data to read.*/
 #   define POLLPRI    (0x0400)
 #   define POLLPRI    (0x0400)
 /*Equivalent to POLLOUT.*/
 /*Equivalent to POLLOUT.*/
 #   define POLLWRNORM (0x0010)
 #   define POLLWRNORM (0x0010)
@@ -894,7 +894,7 @@ static void op_http_stream_init(OpusHTTPStream *_stream){
 /*Close the connection and move it to the free list.
 /*Close the connection and move it to the free list.
   _stream:     The stream containing the free list.
   _stream:     The stream containing the free list.
   _conn:       The connection to close.
   _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.*/
   _gracefully: Whether or not to shut down cleanly.*/
 static void op_http_conn_close(OpusHTTPStream *_stream,OpusHTTPConn *_conn,
 static void op_http_conn_close(OpusHTTPStream *_stream,OpusHTTPConn *_conn,
  OpusHTTPConn **_pnext,int _gracefully){
  OpusHTTPConn **_pnext,int _gracefully){
@@ -1517,10 +1517,17 @@ static long op_bio_retry_ctrl(BIO *_b,int _cmd,long _num,void *_ptr){
   return ret;
   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){
 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->num=0;
-  _b->ptr=NULL;
+# endif
+  BIO_set_data(_b,NULL);
   return 1;
   return 1;
 }
 }
 
 
@@ -1528,6 +1535,7 @@ static int op_bio_retry_free(BIO *_b){
   return _b!=NULL;
   return _b!=NULL;
 }
 }
 
 
+# if OPENSSL_VERSION_NUMBER<0x10100000L
 /*This is not const because OpenSSL doesn't allow it, even though it won't
 /*This is not const because OpenSSL doesn't allow it, even though it won't
    write to it.*/
    write to it.*/
 static BIO_METHOD op_bio_retry_method={
 static BIO_METHOD op_bio_retry_method={
@@ -1542,11 +1550,15 @@ static BIO_METHOD op_bio_retry_method={
   op_bio_retry_free,
   op_bio_retry_free,
   NULL
   NULL
 };
 };
+# endif
 
 
 /*Establish a CONNECT tunnel and pipeline the start of the TLS handshake for
 /*Establish a CONNECT tunnel and pipeline the start of the TLS handshake for
    proxying https URL requests.*/
    proxying https URL requests.*/
 static int op_http_conn_establish_tunnel(OpusHTTPStream *_stream,
 static int op_http_conn_establish_tunnel(OpusHTTPStream *_stream,
  OpusHTTPConn *_conn,op_sock _fd,SSL *_ssl_conn,BIO *_ssl_bio){
  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;
   BIO  *retry_bio;
   char *status_code;
   char *status_code;
   char *next;
   char *next;
@@ -1557,13 +1569,32 @@ static int op_http_conn_establish_tunnel(OpusHTTPStream *_stream,
   ret=op_http_conn_write_fully(_conn,
   ret=op_http_conn_write_fully(_conn,
    _stream->proxy_connect.buf,_stream->proxy_connect.nbuf);
    _stream->proxy_connect.buf,_stream->proxy_connect.nbuf);
   if(OP_UNLIKELY(ret<0))return ret;
   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);
   retry_bio=BIO_new(&op_bio_retry_method);
   if(OP_UNLIKELY(retry_bio==NULL))return OP_EFAULT;
   if(OP_UNLIKELY(retry_bio==NULL))return OP_EFAULT;
+# endif
   SSL_set_bio(_ssl_conn,retry_bio,_ssl_bio);
   SSL_set_bio(_ssl_conn,retry_bio,_ssl_bio);
   SSL_set_connect_state(_ssl_conn);
   SSL_set_connect_state(_ssl_conn);
   /*This shouldn't succeed, since we can't read yet.*/
   /*This shouldn't succeed, since we can't read yet.*/
   OP_ALWAYS_TRUE(SSL_connect(_ssl_conn)<0);
   OP_ALWAYS_TRUE(SSL_connect(_ssl_conn)<0);
   SSL_set_bio(_ssl_conn,_ssl_bio,_ssl_bio);
   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
   /*Only now do we disable write coalescing, to allow the CONNECT
      request and the start of the TLS handshake to be combined.*/
      request and the start of the TLS handshake to be combined.*/
   op_sock_set_tcp_nodelay(_fd,1);
   op_sock_set_tcp_nodelay(_fd,1);
@@ -2200,7 +2231,8 @@ static int op_http_stream_open(OpusHTTPStream *_stream,const char *_url,
     /*Initialize the SSL library if necessary.*/
     /*Initialize the SSL library if necessary.*/
     if(OP_URL_IS_SSL(&_stream->url)&&_stream->ssl_ctx==NULL){
     if(OP_URL_IS_SSL(&_stream->url)&&_stream->ssl_ctx==NULL){
       SSL_CTX *ssl_ctx;
       SSL_CTX *ssl_ctx;
-# if !defined(OPENSSL_NO_LOCKING)
+# if OPENSSL_VERSION_NUMBER<0x10100000L
+#  if !defined(OPENSSL_NO_LOCKING)
       /*The documentation says SSL_library_init() is not reentrant.
       /*The documentation says SSL_library_init() is not reentrant.
         We don't want to add our own depenencies on a threading library, and it
         We don't want to add our own depenencies on a threading library, and it
          appears that it's safe to call OpenSSL's locking functions before the
          appears that it's safe to call OpenSSL's locking functions before the
@@ -2210,12 +2242,16 @@ static int op_http_stream_open(OpusHTTPStream *_stream,const char *_url,
          calling SSL_library_init() at the same time, but there's not much we
          calling SSL_library_init() at the same time, but there's not much we
          can do about that.*/
          can do about that.*/
       CRYPTO_w_lock(CRYPTO_LOCK_SSL);
       CRYPTO_w_lock(CRYPTO_LOCK_SSL);
-# endif
+#  endif
       SSL_library_init();
       SSL_library_init();
       /*Needed to get SHA2 algorithms with old OpenSSL versions.*/
       /*Needed to get SHA2 algorithms with old OpenSSL versions.*/
       OpenSSL_add_ssl_algorithms();
       OpenSSL_add_ssl_algorithms();
-# if !defined(OPENSSL_NO_LOCKING)
+#  if !defined(OPENSSL_NO_LOCKING)
       CRYPTO_w_unlock(CRYPTO_LOCK_SSL);
       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
 # endif
       ssl_ctx=SSL_CTX_new(SSLv23_client_method());
       ssl_ctx=SSL_CTX_new(SSLv23_client_method());
       if(ssl_ctx==NULL)return OP_EFAULT;
       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,
     Otherwise, we'd need a _pnext pointer if we needed to close the connection,
      and re-opening it would re-organize the lists.*/
      and re-opening it would re-organize the lists.*/
   OP_ASSERT(_stream->lru_head==_conn);
   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);
   OP_ASSERT(_buf_size>0);
   pos=_conn->pos;
   pos=_conn->pos;
   end_pos=_conn->end_pos;
   end_pos=_conn->end_pos;

+ 10 - 5
thirdparty/opus/info.c

@@ -199,16 +199,21 @@ static int opus_tags_parse_impl(OpusTags *_tags,
       if(_tags->user_comments[ci]==NULL)return OP_EFAULT;
       if(_tags->user_comments[ci]==NULL)return OP_EFAULT;
       _tags->comment_lengths[ci]=(int)count;
       _tags->comment_lengths[ci]=(int)count;
       _tags->comments=ci+1;
       _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;
     _data+=count;
     len-=count;
     len-=count;
   }
   }
   if(len>0&&(_data[0]&1)){
   if(len>0&&(_data[0]&1)){
     if(len>(opus_uint32)INT_MAX)return OP_EFAULT;
     if(len>(opus_uint32)INT_MAX)return OP_EFAULT;
-    _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;
+    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;
   return 0;
 }
 }
@@ -306,7 +311,7 @@ int opus_tags_add_comment(OpusTags *_tags,const char *_comment){
   if(OP_UNLIKELY(ret<0))return ret;
   if(OP_UNLIKELY(ret<0))return ret;
   comment_len=(int)strlen(_comment);
   comment_len=(int)strlen(_comment);
   comment=op_strdup_with_len(_comment,comment_len);
   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->user_comments[ncomments]=comment;
   _tags->comment_lengths[ncomments]=comment_len;
   _tags->comment_lengths[ncomments]=comment_len;
   _tags->comments=ncomments+1;
   _tags->comments=ncomments+1;

+ 21 - 12
thirdparty/opus/opus/opusfile.h

@@ -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
    These downmix multichannel files to two channels, so they can always return
     samples in the same format for every link in a chained file.
     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
     <tt>libopusfile</tt> provides noise-shaping dithering and, if compiled
     against <tt>libopus</tt>&nbsp;1.1 or later, soft-clipping prevention.
     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.
                       #OP_DEC_FORMAT_FLOAT.
    \param _li        The index of the link from which this packet was decoded.
    \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.
    \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().
             opus_multistream_decode() or opus_multistream_decode_float().
+           Success codes are as follows:
    \retval 0                   Decoding was successful.
    \retval 0                   Decoding was successful.
                                The application has filled the buffer with
                                The application has filled the buffer with
                                 exactly <code>\a _nsamples*\a
                                 exactly <code>\a _nsamples*\a
                                 _nchannels</code> samples in the requested
                                 _nchannels</code> samples in the requested
                                 format.
                                 format.
    \retval #OP_DEC_USE_DEFAULT No decoding was done.
    \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,
 typedef int (*op_decode_cb_func)(void *_ctx,OpusMSDecoder *_decoder,void *_pcm,
  const ogg_packet *_op,int _nsamples,int _nchannels,int _format,int _li);
  const ogg_packet *_op,int _nsamples,int _nchannels,int _format,int _li);
 
 
 /**Sets the packet decode callback function.
 /**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
    A call to this function is no guarantee that the audio will eventually be
     delivered to the application.
     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 _of        The \c OggOpusFile on which to set the decode callback.
    \param _decode_cb The callback function to call.
    \param _decode_cb The callback function to call.
                      This may be <code>NULL</code> to disable calling the
                      This may be <code>NULL</code> to disable calling the

+ 35 - 46
thirdparty/opus/opusfile.c

@@ -505,6 +505,7 @@ static int op_fetch_headers_impl(OggOpusFile *_of,OpusHead *_head,
           Everything else is fatal.*/
           Everything else is fatal.*/
         else if(ret!=OP_ENOTFORMAT)return ret;
         else if(ret!=OP_ENOTFORMAT)return ret;
       }
       }
+      /*TODO: Should a BOS page with no packets be an error?*/
     }
     }
     /*Get the next page.
     /*Get the next page.
       No need to clamp the boundary offset against _of->end, as all errors
       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
   This handles the case where we're at a bitstream boundary and dumps the
    decoding machine.
    decoding machine.
   If the decoding machine is unloaded, it loads it.
   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.
   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,
 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;
   OggOpusLink  *links;
   ogg_uint32_t  cur_serialno;
   ogg_uint32_t  cur_serialno;
   int           seekable;
   int           seekable;
@@ -1838,7 +1836,6 @@ static int op_fetch_and_process_page(OggOpusFile *_of,
   int           ret;
   int           ret;
   /*We shouldn't get here if we have unprocessed packets.*/
   /*We shouldn't get here if we have unprocessed packets.*/
   OP_ASSERT(_of->ready_state<OP_INITSET||_of->op_pos>=_of->op_count);
   OP_ASSERT(_of->ready_state<OP_INITSET||_of->op_pos>=_of->op_count);
-  if(!_readp)return 0;
   seekable=_of->seekable;
   seekable=_of->seekable;
   links=_of->links;
   links=_of->links;
   cur_link=seekable?_of->cur_link:0;
   cur_link=seekable?_of->cur_link:0;
@@ -1847,36 +1844,27 @@ static int op_fetch_and_process_page(OggOpusFile *_of,
   for(;;){
   for(;;){
     ogg_page og;
     ogg_page og;
     OP_ASSERT(_of->ready_state>=OP_OPENED);
     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;
-        _og=NULL;
-      }
-      /*Keep reading until we get a page with the correct serialno.*/
-      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)){
-          /*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;
+    /*If we were given a page to use, use it.*/
+    if(_og!=NULL){
+      *&og=*_og;
+      _og=NULL;
+    }
+    /*Keep reading until we get a page with the correct serialno.*/
+    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)
+     &&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);
     }
     }
-    while(0);
+    /*Bitrate tracking: add the header's bytes here.
+      The body bytes are counted when we consume the packets.*/
+    else _of->bytes_tracked+=og.header_len;
     /*Do we need to load a new machine before submitting the page?
     /*Do we need to load a new machine before submitting the page?
       This is different in the seekable and non-seekable cases.
       This is different in the seekable and non-seekable cases.
       In the seekable case, we already have all the header information loaded
       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(),
         /*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).*/
            keep going (this is possible if end-trimming trimmed them all).*/
         if(_of->op_count<=0)continue;
         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);
         ret=op_make_decode_ready(_of);
         if(OP_UNLIKELY(ret<0))return ret;
         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.
     /*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->prev_page_offset=_page_offset;
         _of->op_count=pi;
         _of->op_count=pi;
         /*If end-trimming didn't trim all the packets, we're done.*/
         /*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;
   _of->samples_tracked=0;
   ret=op_seek_helper(_of,_pos);
   ret=op_seek_helper(_of,_pos);
   if(OP_UNLIKELY(ret<0))return OP_EREAD;
   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.
   /*If we hit EOF, op_fetch_and_process_page() leaves us uninitialized.
     Instead, jump to the end.*/
     Instead, jump to the end.*/
   if(ret==OP_EOF){
   if(ret==OP_EOF){
@@ -2118,7 +2108,6 @@ int op_raw_seek(OggOpusFile *_of,opus_int64 _pos){
     _of->cur_discard_count=0;
     _of->cur_discard_count=0;
     ret=0;
     ret=0;
   }
   }
-  else if(ret>0)ret=0;
   return ret;
   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.*/
   /*Update prev_packet_gp to allow per-packet granule position assignment.*/
   _of->prev_packet_gp=best_gp;
   _of->prev_packet_gp=best_gp;
   _of->prev_page_offset=best_start;
   _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.*/
   /*Verify result.*/
   if(OP_UNLIKELY(op_granpos_cmp(_of->prev_packet_gp,_target_gp)>0)){
   if(OP_UNLIKELY(op_granpos_cmp(_of->prev_packet_gp,_target_gp)>0)){
     return OP_EBADLINK;
     return OP_EBADLINK;
@@ -2589,8 +2578,8 @@ int op_pcm_seek(OggOpusFile *_of,ogg_int64_t _pcm_offset){
     if(op_pos<op_count)break;
     if(op_pos<op_count)break;
     /*We skipped all the packets on this page.
     /*We skipped all the packets on this page.
       Fetch another.*/
       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));
   OP_ALWAYS_TRUE(!op_granpos_diff(&diff,prev_packet_gp,pcm_start));
   /*We skipped too far.
   /*We skipped too far.
@@ -2854,7 +2843,7 @@ static int op_read_native(OggOpusFile *_of,
       }
       }
     }
     }
     /*Suck in another page.*/
     /*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(OP_UNLIKELY(ret==OP_EOF)){
       if(_li!=NULL)*_li=_of->cur_link;
       if(_li!=NULL)*_li=_of->cur_link;
       return 0;
       return 0;