shithub: opus

Download patch

ref: e7028175af1661abaa3447a6a84750662ab8dfe6
parent: 8365b5d00df0d1129a30550f451fb62a24e1bc00
author: Gregory Maxwell <[email protected]>
date: Sat Nov 19 18:58:09 EST 2011

40/60ms MDCT/Hybrid were not able to reach maximum bitrate. Now they can.

Also change the packet length in the API from int to opus_int32
because repacketized frames are able to go beyond 32767 bytes
in size.

--- a/include/opus.h
+++ b/include/opus.h
@@ -131,7 +131,7 @@
   * <li>audio_frame is the audio data in opus_int16 (or float for opus_encode_float())</li>
   * <li>frame_size is the duration of the frame in samples (per channel)</li>
   * <li>packet is the byte array to which the compressed data is written</li>
-  * <li>max_packet is the maximum number of bytes that can be written in the packet (1276 bytes is recommended)</li>
+  * <li>max_packet is the maximum number of bytes that can be written in the packet (4000 bytes is recommended)</li>
   * </ul>
   *
   * opus_encode() and opus_encode_frame() return the number of bytes actually written to the packet.
@@ -224,15 +224,15 @@
   * @param [in] pcm <tt>opus_int16*</tt>: Input signal (interleaved if 2 channels). length is frame_size*channels*sizeof(opus_int16)
   * @param [in] frame_size <tt>int</tt>: Number of samples per frame of input signal
   * @param [out] data <tt>char*</tt>: Output payload (at least max_data_bytes long)
-  * @param [in] max_data_bytes <tt>int</tt>: Allocated memory for payload; don't use for controlling bitrate
+  * @param [in] max_data_bytes <tt>opus_int32</tt>: Allocated memory for payload; don't use for controlling bitrate
   * @returns length of the data payload (in bytes) or @ref errorcodes
   */
-OPUS_EXPORT int opus_encode(
+OPUS_EXPORT opus_int32 opus_encode(
     OpusEncoder *st,
     const opus_int16 *pcm,
     int frame_size,
     unsigned char *data,
-    int max_data_bytes
+    opus_int32 max_data_bytes
 );
 
 /** Encodes an Opus frame from floating point input.
@@ -244,15 +244,15 @@
   * @param [in] pcm <tt>float*</tt>: Input signal (interleaved if 2 channels). length is frame_size*channels*sizeof(float)
   * @param [in] frame_size <tt>int</tt>: Number of samples per frame of input signal
   * @param [out] data <tt>char*</tt>: Output payload (at least max_data_bytes long)
-  * @param [in] max_data_bytes <tt>int</tt>: Allocated memory for payload; don't use for controlling bitrate
+  * @param [in] max_data_bytes <tt>opus_int32</tt>: Allocated memory for payload; don't use for controlling bitrate
   * @returns length of the data payload (in bytes) or @ref errorcodes
   */
-OPUS_EXPORT int opus_encode_float(
+OPUS_EXPORT opus_int32 opus_encode_float(
     OpusEncoder *st,
     const float *pcm,
     int frame_size,
     unsigned char *data,
-    int max_data_bytes
+    opus_int32 max_data_bytes
 );
 
 /** Frees an OpusEncoder allocated by opus_encoder_create.
@@ -361,7 +361,7 @@
 /** Decode an Opus frame
   * @param [in] st <tt>OpusDecoder*</tt>: Decoder state
   * @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss
-  * @param [in] len <tt>int</tt>: Number of bytes in payload*
+  * @param [in] len <tt>opus_int32</tt>: Number of bytes in payload*
   * @param [out] pcm <tt>opus_int16*</tt>: Output signal (interleaved if 2 channels). length
   *  is frame_size*channels*sizeof(opus_int16)
   * @param [in] frame_size Number of samples per channel of available space in *pcm,
@@ -373,7 +373,7 @@
 OPUS_EXPORT int opus_decode(
     OpusDecoder *st,
     const unsigned char *data,
-    int len,
+    opus_int32 len,
     opus_int16 *pcm,
     int frame_size,
     int decode_fec
@@ -382,7 +382,7 @@
 /** Decode an opus frame with floating point output
   * @param [in] st <tt>OpusDecoder*</tt>: Decoder state
   * @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss
-  * @param [in] len <tt>int</tt>: Number of bytes in payload
+  * @param [in] len <tt>opus_int32</tt>: Number of bytes in payload
   * @param [out] pcm <tt>float*</tt>: Output signal (interleaved if 2 channels). length
   *  is frame_size*channels*sizeof(float)
   * @param [in] frame_size Number of samples per channel of available space in *pcm,
@@ -394,7 +394,7 @@
 OPUS_EXPORT int opus_decode_float(
     OpusDecoder *st,
     const unsigned char *data,
-    int len,
+    opus_int32 len,
     float *pcm,
     int frame_size,
     int decode_fec
@@ -419,7 +419,7 @@
   * This function does not copy the frames, the returned pointers are pointers into
   * the input packet.
   * @param [in] data <tt>char*</tt>: Opus packet to be parsed
-  * @param [in] len <tt>int</tt>: size of data
+  * @param [in] len <tt>opus_int32</tt>: size of data
   * @param [out] out_toc <tt>char*</tt>: TOC pointer
   * @param [out] frames <tt>char*[48]</tt> encapsulated frames
   * @param [out] size <tt>short[48]</tt> sizes of the encapsulated frames
@@ -428,7 +428,7 @@
   */
 OPUS_EXPORT int opus_packet_parse(
    const unsigned char *data,
-   int len,
+   opus_int32 len,
    unsigned char *out_toc,
    const unsigned char *frames[48],
    short size[48],
@@ -463,20 +463,20 @@
 
 /** Gets the number of frames in an Opus packet.
   * @param [in] packet <tt>char*</tt>: Opus packet
-  * @param [in] len <tt>int</tt>: Length of packet
+  * @param [in] len <tt>opus_int32</tt>: Length of packet
   * @returns Number of frames
   * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
   */
-OPUS_EXPORT int opus_packet_get_nb_frames(const unsigned char packet[], int len);
+OPUS_EXPORT int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len);
 
 /** Gets the number of samples of an Opus packet.
   * @param [in] dec <tt>OpusDecoder*</tt>: Decoder state
   * @param [in] packet <tt>char*</tt>: Opus packet
-  * @param [in] len <tt>int</tt>: Length of packet
+  * @param [in] len <tt>opus_int32</tt>: Length of packet
   * @returns Number of samples
   * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
   */
-OPUS_EXPORT int opus_decoder_get_nb_samples(const OpusDecoder *dec, const unsigned char packet[], int len);
+OPUS_EXPORT int opus_decoder_get_nb_samples(const OpusDecoder *dec, const unsigned char packet[], opus_int32 len);
 /**@}*/
 
 /** @defgroup repacketizer Repacketizer
@@ -497,13 +497,13 @@
 
 OPUS_EXPORT void opus_repacketizer_destroy(OpusRepacketizer *rp);
 
-OPUS_EXPORT int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data, int len);
+OPUS_EXPORT int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data, opus_int32 len);
 
-OPUS_EXPORT opus_int32 opus_repacketizer_out_range(OpusRepacketizer *rp, int begin, int end, unsigned char *data, int maxlen);
+OPUS_EXPORT opus_int32 opus_repacketizer_out_range(OpusRepacketizer *rp, int begin, int end, unsigned char *data, opus_int32 maxlen);
 
 OPUS_EXPORT int opus_repacketizer_get_nb_frames(OpusRepacketizer *rp);
 
-OPUS_EXPORT opus_int32 opus_repacketizer_out(OpusRepacketizer *rp, unsigned char *data, int maxlen);
+OPUS_EXPORT opus_int32 opus_repacketizer_out(OpusRepacketizer *rp, unsigned char *data, opus_int32 maxlen);
 
 /**@}*/
 
--- a/src/opus_decoder.c
+++ b/src/opus_decoder.c
@@ -187,7 +187,7 @@
 }
 
 static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
-      int len, opus_val16 *pcm, int frame_size, int decode_fec)
+      opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec)
 {
    void *silk_dec;
    CELTDecoder *celt_dec;
@@ -505,7 +505,7 @@
 
 }
 
-static int parse_size(const unsigned char *data, int len, short *size)
+static int parse_size(const unsigned char *data, opus_int32 len, short *size)
 {
    if (len<1)
    {
@@ -525,7 +525,7 @@
    }
 }
 
-static int opus_packet_parse_impl(const unsigned char *data, int len,
+static int opus_packet_parse_impl(const unsigned char *data, opus_int32 len,
       int self_delimited, unsigned char *out_toc,
       const unsigned char *frames[48], short size[48], int *payload_offset)
 {
@@ -672,7 +672,7 @@
    return count;
 }
 
-int opus_packet_parse(const unsigned char *data, int len,
+int opus_packet_parse(const unsigned char *data, opus_int32 len,
       unsigned char *out_toc, const unsigned char *frames[48],
       short size[48], int *payload_offset)
 {
@@ -681,7 +681,7 @@
 }
 
 int opus_decode_native(OpusDecoder *st, const unsigned char *data,
-      int len, opus_val16 *pcm, int frame_size, int decode_fec,
+      opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec,
       int self_delimited, int *packet_offset)
 {
    int i, nb_samples;
@@ -732,7 +732,7 @@
 #ifdef FIXED_POINT
 
 int opus_decode(OpusDecoder *st, const unsigned char *data,
-      int len, opus_val16 *pcm, int frame_size, int decode_fec)
+      opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec)
 {
    return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL);
 }
@@ -739,7 +739,7 @@
 
 #ifndef DISABLE_FLOAT_API
 int opus_decode_float(OpusDecoder *st, const unsigned char *data,
-      int len, float *pcm, int frame_size, int decode_fec)
+      opus_int32 len, float *pcm, int frame_size, int decode_fec)
 {
    VARDECL(opus_int16, out);
    int ret, i;
@@ -761,7 +761,7 @@
 
 #else
 int opus_decode(OpusDecoder *st, const unsigned char *data,
-      int len, opus_int16 *pcm, int frame_size, int decode_fec)
+      opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec)
 {
    VARDECL(float, out);
    int ret, i;
@@ -782,7 +782,7 @@
 }
 
 int opus_decode_float(OpusDecoder *st, const unsigned char *data,
-      int len, opus_val16 *pcm, int frame_size, int decode_fec)
+      opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec)
 {
    return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL);
 }
@@ -902,7 +902,7 @@
    return (data[0]&0x4) ? 2 : 1;
 }
 
-int opus_packet_get_nb_frames(const unsigned char packet[], int len)
+int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len)
 {
    int count;
    if (len<1)
@@ -919,7 +919,7 @@
 }
 
 int opus_decoder_get_nb_samples(const OpusDecoder *dec,
-      const unsigned char packet[], int len)
+      const unsigned char packet[], opus_int32 len)
 {
    int samples;
    int count = opus_packet_get_nb_frames(packet, len);
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -220,7 +220,7 @@
     return OPUS_OK;
 }
 
-static int pad_frame(unsigned char *data, int len, int new_len)
+static int pad_frame(unsigned char *data, opus_int32 len, opus_int32 new_len)
 {
    if (len == new_len)
       return 0;
@@ -438,11 +438,11 @@
 #ifdef FIXED_POINT
 #define opus_encode_native opus_encode
 int opus_encode(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
-                unsigned char *data, int max_data_bytes)
+                unsigned char *data, opus_int32 out_data_bytes)
 #else
 #define opus_encode_native opus_encode_float
 int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
-                      unsigned char *data, int max_data_bytes)
+                      unsigned char *data, opus_int32 out_data_bytes)
 #endif
 {
     void *silk_enc;
@@ -468,11 +468,12 @@
     int frame_rate;
     opus_int32 max_rate;
     int curr_bandwidth;
+    opus_int32 max_data_bytes;
     VARDECL(opus_val16, tmp_prefill);
 
     ALLOC_STACK;
 
-    max_data_bytes = IMIN(1276, max_data_bytes);
+    max_data_bytes = IMIN(1276, out_data_bytes);
 
     st->rangeFinal = 0;
     if (400*frame_size != st->Fs && 200*frame_size != st->Fs && 100*frame_size != st->Fs &&
@@ -746,11 +747,11 @@
        int nb_frames;
        int bak_mode, bak_bandwidth, bak_channels, bak_to_mono;
        OpusRepacketizer rp;
-       int bytes_per_frame;
+       opus_int32 bytes_per_frame;
 
 
        nb_frames = frame_size > st->Fs/25 ? 3 : 2;
-       bytes_per_frame = max_data_bytes/nb_frames-3;
+       bytes_per_frame = IMIN(1276,(out_data_bytes-3)/nb_frames);
 
        ALLOC(tmp_data, nb_frames*bytes_per_frame, unsigned char);
 
@@ -783,7 +784,7 @@
           if (ret<0)
              return OPUS_INTERNAL_ERROR;
        }
-       ret = opus_repacketizer_out(&rp, data, max_data_bytes);
+       ret = opus_repacketizer_out(&rp, data, out_data_bytes);
        if (ret<0)
           return OPUS_INTERNAL_ERROR;
 
@@ -1222,7 +1223,7 @@
 
 #ifndef DISABLE_FLOAT_API
 int opus_encode_float(OpusEncoder *st, const float *pcm, int frame_size,
-      unsigned char *data, int max_data_bytes)
+      unsigned char *data, opus_int32 max_data_bytes)
 {
    int i, ret;
    VARDECL(opus_int16, in);
@@ -1242,7 +1243,7 @@
 
 #else
 int opus_encode(OpusEncoder *st, const opus_int16 *pcm, int frame_size,
-      unsigned char *data, int max_data_bytes)
+      unsigned char *data, opus_int32 max_data_bytes)
 {
    int i, ret;
    VARDECL(float, in);
--- a/src/opus_multistream.c
+++ b/src/opus_multistream.c
@@ -227,7 +227,7 @@
     const opus_val16 *pcm,
     int frame_size,
     unsigned char *data,
-    int max_data_bytes
+    opus_int32 max_data_bytes
 )
 {
    int coupled_size;
@@ -309,7 +309,7 @@
     const float *pcm,
     int frame_size,
     unsigned char *data,
-    int max_data_bytes
+    opus_int32 max_data_bytes
 )
 {
    int i, ret;
@@ -333,7 +333,7 @@
     const opus_int16 *pcm,
     int frame_size,
     unsigned char *data,
-    int max_data_bytes
+    opus_int32 max_data_bytes
 )
 {
    int i, ret;
@@ -587,7 +587,7 @@
 static int opus_multistream_decode_native(
       OpusMSDecoder *st,
       const unsigned char *data,
-      int len,
+      opus_int32 len,
       opus_val16 *pcm,
       int frame_size,
       int decode_fec
@@ -693,7 +693,7 @@
 int opus_multistream_decode(
       OpusMSDecoder *st,
       const unsigned char *data,
-      int len,
+      opus_int32 len,
       opus_int16 *pcm,
       int frame_size,
       int decode_fec
@@ -704,7 +704,7 @@
 
 #ifndef DISABLE_FLOAT_API
 int opus_multistream_decode_float(OpusMSDecoder *st, const unsigned char *data,
-      int len, float *pcm, int frame_size, int decode_fec)
+      opus_int32 len, float *pcm, int frame_size, int decode_fec)
 {
    VARDECL(opus_int16, out);
    int ret, i;
@@ -726,7 +726,7 @@
 #else
 
 int opus_multistream_decode(OpusMSDecoder *st, const unsigned char *data,
-      int len, opus_int16 *pcm, int frame_size, int decode_fec)
+      opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec)
 {
    VARDECL(float, out);
    int ret, i;
@@ -747,7 +747,7 @@
 int opus_multistream_decode_float(
       OpusMSDecoder *st,
       const unsigned char *data,
-      int len,
+      opus_int32 len,
       float *pcm,
       int frame_size,
       int decode_fec