tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

extensions.c (23462B)


      1 /* Copyright (c) 2022 Amazon */
      2 /*
      3   Redistribution and use in source and binary forms, with or without
      4   modification, are permitted provided that the following conditions
      5   are met:
      6 
      7   - Redistributions of source code must retain the above copyright
      8   notice, this list of conditions and the following disclaimer.
      9 
     10   - Redistributions in binary form must reproduce the above copyright
     11   notice, this list of conditions and the following disclaimer in the
     12   documentation and/or other materials provided with the distribution.
     13 
     14   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     15   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     16   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     17   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
     18   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     19   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     20   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     21   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     22   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     23   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     24   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25 */
     26 
     27 #ifdef HAVE_CONFIG_H
     28 #include "config.h"
     29 #endif
     30 
     31 
     32 #include "opus_types.h"
     33 #include "opus_defines.h"
     34 #include "arch.h"
     35 #include "os_support.h"
     36 #include "opus_private.h"
     37 
     38 
     39 /* Given an extension payload (i.e., excluding the initial ID byte), advance
     40    data to the next extension and return the length of the remaining
     41    extensions.
     42   N.B., a "Repeat These Extensions" extension (ID==2) does not advance past
     43    the repeated extension payloads.
     44   That requires higher-level logic. */
     45 static opus_int32 skip_extension_payload(const unsigned char **pdata,
     46 opus_int32 len, opus_int32 *pheader_size, int id_byte,
     47 opus_int32 trailing_short_len)
     48 {
     49   const unsigned char *data;
     50   opus_int32 header_size;
     51   int id, L;
     52   data = *pdata;
     53   header_size = 0;
     54   id = id_byte>>1;
     55   L = id_byte&1;
     56   if ((id == 0 && L == 1) || id == 2)
     57   {
     58      /* Nothing to do. */
     59   } else if (id > 0 && id < 32)
     60   {
     61      if (len < L)
     62         return -1;
     63      data += L;
     64      len -= L;
     65   } else {
     66      if (L==0)
     67      {
     68         if (len < trailing_short_len) return -1;
     69         data += len - trailing_short_len;
     70         len = trailing_short_len;
     71      } else {
     72         opus_int32 bytes=0;
     73         opus_int32 lacing;
     74         do {
     75            if (len < 1)
     76               return -1;
     77            lacing = *data++;
     78            bytes += lacing;
     79            header_size++;
     80            len -= lacing + 1;
     81         } while (lacing == 255);
     82         if (len < 0)
     83            return -1;
     84         data += bytes;
     85      }
     86   }
     87   *pdata = data;
     88   *pheader_size = header_size;
     89   return len;
     90 }
     91 
     92 /* Given an extension, advance data to the next extension and return the
     93   length of the remaining extensions.
     94   N.B., a "Repeat These Extensions" extension (ID==2) only advances past the
     95    extension ID byte.
     96   Higher-level logic is required to skip the extension payloads that come
     97    after it.*/
     98 static opus_int32 skip_extension(const unsigned char **pdata, opus_int32 len,
     99 opus_int32 *pheader_size)
    100 {
    101   const unsigned char *data;
    102   int id_byte;
    103   if (len == 0) {
    104      *pheader_size = 0;
    105      return 0;
    106   }
    107   if (len < 1)
    108      return -1;
    109   data = *pdata;
    110   id_byte = *data++;
    111   len--;
    112   len = skip_extension_payload(&data, len, pheader_size, id_byte, 0);
    113   if (len >= 0) {
    114      *pdata = data;
    115      (*pheader_size)++;
    116   }
    117   return len;
    118 }
    119 
    120 void opus_extension_iterator_init(OpusExtensionIterator *iter,
    121 const unsigned char *data, opus_int32 len, opus_int32 nb_frames) {
    122   celt_assert(len >= 0);
    123   celt_assert(data != NULL || len == 0);
    124   celt_assert(nb_frames >= 0 && nb_frames <= 48);
    125   iter->repeat_data = iter->curr_data = iter->data = data;
    126   iter->last_long = iter->src_data = NULL;
    127   iter->curr_len = iter->len = len;
    128   iter->repeat_len = iter->src_len = 0;
    129   iter->trailing_short_len = 0;
    130   iter->frame_max = iter->nb_frames = nb_frames;
    131   iter->repeat_frame = iter->curr_frame = 0;
    132   iter->repeat_l = 0;
    133 }
    134 
    135 /* Reset the iterator so it can start iterating again from the first
    136    extension. */
    137 void opus_extension_iterator_reset(OpusExtensionIterator *iter) {
    138   iter->repeat_data = iter->curr_data = iter->data;
    139   iter->last_long = NULL;
    140   iter->curr_len = iter->len;
    141   iter->repeat_frame = iter->curr_frame = 0;
    142   iter->trailing_short_len = 0;
    143 }
    144 
    145 /* Tell the iterator not to return any extensions for frames of index
    146    frame_max or larger.
    147   This can allow it to stop iterating early if these extensions are not
    148    needed. */
    149 void opus_extension_iterator_set_frame_max(OpusExtensionIterator *iter,
    150 int frame_max) {
    151   iter->frame_max = frame_max;
    152 }
    153 
    154 /* Return the next repeated extension.
    155   The return value is non-zero if one is found, negative on error, or 0 if we
    156    have finished repeating extensions. */
    157 static int opus_extension_iterator_next_repeat(OpusExtensionIterator *iter,
    158 opus_extension_data *ext) {
    159   opus_int32 header_size;
    160   celt_assert(iter->repeat_frame > 0);
    161   for (;iter->repeat_frame < iter->nb_frames; iter->repeat_frame++) {
    162      while (iter->src_len > 0) {
    163         const unsigned char *curr_data0;
    164         int repeat_id_byte;
    165         repeat_id_byte = *iter->src_data;
    166         iter->src_len = skip_extension(&iter->src_data, iter->src_len,
    167          &header_size);
    168         /* We skipped this extension earlier, so it should not fail now. */
    169         celt_assert(iter->src_len >= 0);
    170         /* Don't repeat padding or frame separators with a 0 increment. */
    171         if (repeat_id_byte <= 3) continue;
    172         /* If the "Repeat These Extensions" extension had L == 0 and this
    173             is the last repeated long extension, then force decoding the
    174             payload with L = 0. */
    175         if (iter->repeat_l == 0
    176          && iter->repeat_frame + 1 >= iter->nb_frames
    177          && iter->src_data == iter->last_long) {
    178            repeat_id_byte &= ~1;
    179         }
    180         curr_data0 = iter->curr_data;
    181         iter->curr_len = skip_extension_payload(&iter->curr_data,
    182          iter->curr_len, &header_size, repeat_id_byte,
    183          iter->trailing_short_len);
    184         if (iter->curr_len < 0) {
    185            return OPUS_INVALID_PACKET;
    186         }
    187         celt_assert(iter->curr_data - iter->data
    188          == iter->len - iter->curr_len);
    189         /* If we were asked to stop at frame_max, skip extensions for later
    190             frames. */
    191         if (iter->repeat_frame >= iter->frame_max) {
    192            continue;
    193         }
    194         if (ext != NULL) {
    195            ext->id = repeat_id_byte >> 1;
    196            ext->frame = iter->repeat_frame;
    197            ext->data = curr_data0 + header_size;
    198            ext->len = iter->curr_data - curr_data0 - header_size;
    199         }
    200         return 1;
    201      }
    202      /* We finished repeating the extensions for this frame. */
    203      iter->src_data = iter->repeat_data;
    204      iter->src_len = iter->repeat_len;
    205   }
    206   /* We finished repeating extensions. */
    207   iter->repeat_data = iter->curr_data;
    208   iter->last_long = NULL;
    209   /* If L == 0, advance the frame number to handle the case where we did
    210       not consume all of the data with an L == 0 long extension. */
    211   if (iter->repeat_l == 0) {
    212      iter->curr_frame++;
    213      /* Ignore additional padding if this was already the last frame. */
    214      if (iter->curr_frame >= iter->nb_frames) {
    215         iter->curr_len = 0;
    216      }
    217   }
    218   iter->repeat_frame = 0;
    219   return 0;
    220 }
    221 
    222 /* Return the next extension (excluding real padding, separators, and repeat
    223    indicators, but including the repeated extensions) in bitstream order.
    224   Due to the extension repetition mechanism, extensions are not necessarily
    225    returned in frame order. */
    226 int opus_extension_iterator_next(OpusExtensionIterator *iter,
    227 opus_extension_data *ext) {
    228   opus_int32 header_size;
    229   if (iter->curr_len < 0) {
    230      return OPUS_INVALID_PACKET;
    231   }
    232   if (iter->repeat_frame > 0) {
    233      int ret;
    234      /* We are in the process of repeating some extensions. */
    235      ret = opus_extension_iterator_next_repeat(iter, ext);
    236      if (ret) return ret;
    237   }
    238   /* Checking this here allows opus_extension_iterator_set_frame_max() to be
    239       called at any point. */
    240   if (iter->curr_frame >= iter->frame_max) {
    241      return 0;
    242   }
    243   while (iter->curr_len > 0) {
    244      const unsigned char *curr_data0;
    245      int id;
    246      int L;
    247      curr_data0 = iter->curr_data;
    248      id = *curr_data0>>1;
    249      L = *curr_data0&1;
    250      iter->curr_len = skip_extension(&iter->curr_data, iter->curr_len,
    251       &header_size);
    252      if (iter->curr_len < 0) {
    253         return OPUS_INVALID_PACKET;
    254      }
    255      celt_assert(iter->curr_data - iter->data == iter->len - iter->curr_len);
    256      if (id == 1) {
    257         if (L == 0) {
    258            iter->curr_frame++;
    259         }
    260         else {
    261            /* A frame increment of 0 is a no-op. */
    262            if (!curr_data0[1]) continue;
    263            iter->curr_frame += curr_data0[1];
    264         }
    265         if (iter->curr_frame >= iter->nb_frames) {
    266            iter->curr_len = -1;
    267            return OPUS_INVALID_PACKET;
    268         }
    269         /* If we were asked to stop at frame_max, skip extensions for later
    270             frames. */
    271         if (iter->curr_frame >= iter->frame_max) {
    272            iter->curr_len = 0;
    273         }
    274         iter->repeat_data = iter->curr_data;
    275         iter->last_long = NULL;
    276         iter->trailing_short_len = 0;
    277      }
    278      else if (id == 2) {
    279         int ret;
    280         iter->repeat_l = L;
    281         iter->repeat_frame = iter->curr_frame + 1;
    282         iter->repeat_len = curr_data0 - iter->repeat_data;
    283         iter->src_data = iter->repeat_data;
    284         iter->src_len = iter->repeat_len;
    285         ret = opus_extension_iterator_next_repeat(iter, ext);
    286         if (ret) return ret;
    287      }
    288      else if (id > 2) {
    289         /* Update the location of the last long extension.
    290            This lets us know when we need to modify the last L flag if we
    291             repeat these extensions with L=0. */
    292         if (id >= 32) {
    293           iter->last_long = iter->curr_data;
    294           iter->trailing_short_len = 0;
    295         }
    296         /* Otherwise, keep track of how many payload bytes follow the last
    297             long extension. */
    298         else iter->trailing_short_len += L;
    299         if (ext != NULL) {
    300            ext->id = id;
    301            ext->frame = iter->curr_frame;
    302            ext->data = curr_data0 + header_size;
    303            ext->len = iter->curr_data - curr_data0 - header_size;
    304         }
    305         return 1;
    306      }
    307   }
    308   return 0;
    309 }
    310 
    311 int opus_extension_iterator_find(OpusExtensionIterator *iter,
    312 opus_extension_data *ext, int id) {
    313   opus_extension_data curr_ext;
    314   int ret;
    315   for(;;) {
    316      ret = opus_extension_iterator_next(iter, &curr_ext);
    317      if (ret <= 0) {
    318         return ret;
    319      }
    320      if (curr_ext.id == id) {
    321         *ext = curr_ext;
    322         return ret;
    323      }
    324   }
    325 }
    326 
    327 /* Count the number of extensions, excluding real padding, separators, and
    328    repeat indicators, but including the repeated extensions. */
    329 opus_int32 opus_packet_extensions_count(const unsigned char *data,
    330 opus_int32 len, int nb_frames)
    331 {
    332   OpusExtensionIterator iter;
    333   int count;
    334   opus_extension_iterator_init(&iter, data, len, nb_frames);
    335   for (count=0; opus_extension_iterator_next(&iter, NULL) > 0; count++);
    336   return count;
    337 }
    338 
    339 /* Count the number of extensions for each frame, excluding real padding and
    340    separators and repeat indicators, but including the repeated extensions. */
    341 opus_int32 opus_packet_extensions_count_ext(const unsigned char *data,
    342 opus_int32 len, opus_int32 *nb_frame_exts, int nb_frames) {
    343   OpusExtensionIterator iter;
    344   opus_extension_data ext;
    345   int count;
    346   opus_extension_iterator_init(&iter, data, len, nb_frames);
    347   OPUS_CLEAR(nb_frame_exts, nb_frames);
    348   for (count=0; opus_extension_iterator_next(&iter, &ext) > 0; count++) {
    349      nb_frame_exts[ext.frame]++;
    350   }
    351   return count;
    352 }
    353 
    354 /* Extract extensions from Opus padding (excluding real padding, separators,
    355    and repeat indicators, but including the repeated extensions) in bitstream
    356    order.
    357   Due to the extension repetition mechanism, extensions are not necessarily
    358    returned in frame order. */
    359 opus_int32 opus_packet_extensions_parse(const unsigned char *data,
    360 opus_int32 len, opus_extension_data *extensions, opus_int32 *nb_extensions,
    361 int nb_frames) {
    362   OpusExtensionIterator iter;
    363   int count;
    364   int ret;
    365   celt_assert(nb_extensions != NULL);
    366   celt_assert(extensions != NULL || *nb_extensions == 0);
    367   opus_extension_iterator_init(&iter, data, len, nb_frames);
    368   for (count=0;; count++) {
    369      opus_extension_data ext;
    370      ret = opus_extension_iterator_next(&iter, &ext);
    371      if (ret <= 0) break;
    372      if (count == *nb_extensions) {
    373         return OPUS_BUFFER_TOO_SMALL;
    374      }
    375      extensions[count] = ext;
    376   }
    377   *nb_extensions = count;
    378   return ret;
    379 }
    380 
    381 /* Extract extensions from Opus padding (excluding real padding, separators,
    382    and repeat indicators, but including the repeated extensions) in frame
    383    order.
    384   nb_frame_exts must be filled with the output of
    385    opus_packet_extensions_count_ext(). */
    386 opus_int32 opus_packet_extensions_parse_ext(const unsigned char *data,
    387 opus_int32 len, opus_extension_data *extensions, opus_int32 *nb_extensions,
    388 const opus_int32 *nb_frame_exts, int nb_frames) {
    389   OpusExtensionIterator iter;
    390   opus_extension_data ext;
    391   opus_int32 nb_frames_cum[49];
    392   int count;
    393   int prev_total;
    394   int ret;
    395   celt_assert(nb_extensions != NULL);
    396   celt_assert(extensions != NULL || *nb_extensions == 0);
    397   celt_assert(nb_frames <= 48);
    398   /* Convert the frame extension count array to a cumulative sum. */
    399   prev_total = 0;
    400   for (count=0; count<nb_frames; count++) {
    401      int total;
    402      total = nb_frame_exts[count] + prev_total;
    403      nb_frames_cum[count] = prev_total;
    404      prev_total = total;
    405   }
    406   nb_frames_cum[count] = prev_total;
    407   opus_extension_iterator_init(&iter, data, len, nb_frames);
    408   for (count=0;; count++) {
    409      opus_int32 idx;
    410      ret = opus_extension_iterator_next(&iter, &ext);
    411      if (ret <= 0) break;
    412      idx = nb_frames_cum[ext.frame]++;
    413      if (idx >= *nb_extensions) {
    414         return OPUS_BUFFER_TOO_SMALL;
    415      }
    416      celt_assert(idx < nb_frames_cum[ext.frame + 1]);
    417      extensions[idx] = ext;
    418   }
    419   *nb_extensions = count;
    420   return ret;
    421 }
    422 
    423 static int write_extension_payload(unsigned char *data, opus_int32 len,
    424 opus_int32 pos, const opus_extension_data *ext, int last) {
    425   celt_assert(ext->id >= 3 && ext->id <= 127);
    426   if (ext->id < 32)
    427   {
    428      if (ext->len < 0 || ext->len > 1)
    429         return OPUS_BAD_ARG;
    430      if (ext->len > 0) {
    431         if (len-pos < ext->len)
    432            return OPUS_BUFFER_TOO_SMALL;
    433         if (data) data[pos] = ext->data[0];
    434         pos++;
    435      }
    436   } else {
    437      opus_int32 length_bytes;
    438      if (ext->len < 0)
    439         return OPUS_BAD_ARG;
    440      length_bytes = 1 + ext->len/255;
    441      if (last)
    442         length_bytes = 0;
    443      if (len-pos < length_bytes + ext->len)
    444         return OPUS_BUFFER_TOO_SMALL;
    445      if (!last)
    446      {
    447         opus_int32 j;
    448         for (j=0;j<ext->len/255;j++) {
    449            if (data) data[pos] = 255;
    450            pos++;
    451         }
    452         if (data) data[pos] = ext->len % 255;
    453         pos++;
    454      }
    455      if (data) OPUS_COPY(&data[pos], ext->data, ext->len);
    456      pos += ext->len;
    457   }
    458   return pos;
    459 }
    460 
    461 static int write_extension(unsigned char *data, opus_int32 len, opus_int32 pos,
    462 const opus_extension_data *ext, int last) {
    463   if (len-pos < 1)
    464      return OPUS_BUFFER_TOO_SMALL;
    465   celt_assert(ext->id >= 3 && ext->id <= 127);
    466   if (data) data[pos] = (ext->id<<1) + (ext->id < 32 ? ext->len : !last);
    467   pos++;
    468   return write_extension_payload(data, len, pos, ext, last);
    469 }
    470 
    471 opus_int32 opus_packet_extensions_generate(unsigned char *data, opus_int32 len,
    472 const opus_extension_data  *extensions, opus_int32 nb_extensions,
    473 int nb_frames, int pad)
    474 {
    475   opus_int32 frame_min_idx[48];
    476   opus_int32 frame_max_idx[48];
    477   opus_int32 frame_repeat_idx[48];
    478   opus_int32 i;
    479   int f;
    480   int curr_frame = 0;
    481   opus_int32 pos = 0;
    482   opus_int32 written = 0;
    483 
    484   celt_assert(len >= 0);
    485   if (nb_frames > 48) return OPUS_BAD_ARG;
    486 
    487   /* Do a little work up-front to make this O(nb_extensions) instead of
    488       O(nb_extensions*nb_frames) so long as the extensions are in frame
    489       order (without requiring that they be in frame order). */
    490   for (f=0;f<nb_frames;f++) frame_min_idx[f] = nb_extensions;
    491   OPUS_CLEAR(frame_max_idx, nb_frames);
    492   for (i=0;i<nb_extensions;i++)
    493   {
    494      f = extensions[i].frame;
    495      if (f < 0 || f >= nb_frames) return OPUS_BAD_ARG;
    496      if (extensions[i].id < 3 || extensions[i].id > 127) return OPUS_BAD_ARG;
    497      frame_min_idx[f] = IMIN(frame_min_idx[f], i);
    498      frame_max_idx[f] = IMAX(frame_max_idx[f], i+1);
    499   }
    500   for (f=0;f<nb_frames;f++) frame_repeat_idx[f] = frame_min_idx[f];
    501   for (f=0;f<nb_frames;f++)
    502   {
    503      opus_int32 last_long_idx;
    504      int repeat_count;
    505      repeat_count = 0;
    506      last_long_idx = -1;
    507      if (f + 1 < nb_frames)
    508      {
    509         for (i=frame_min_idx[f];i<frame_max_idx[f];i++)
    510         {
    511            if (extensions[i].frame == f)
    512            {
    513               int g;
    514               /* Test if we can repeat this extension in future frames. */
    515               for (g=f+1;g<nb_frames;g++)
    516               {
    517                  if (frame_repeat_idx[g] >= frame_max_idx[g]) break;
    518                  celt_assert(extensions[frame_repeat_idx[g]].frame == g);
    519                  if (extensions[frame_repeat_idx[g]].id != extensions[i].id)
    520                  {
    521                     break;
    522                  }
    523                  if (extensions[frame_repeat_idx[g]].id < 32
    524                    && extensions[frame_repeat_idx[g]].len
    525                    != extensions[i].len)
    526                  {
    527                     break;
    528                  }
    529               }
    530               if (g < nb_frames) break;
    531               /* We can! */
    532               /* If this is a long extension, save the index of the last
    533                   instance, so we can modify its L flag. */
    534               if (extensions[i].id >= 32) {
    535                  last_long_idx = frame_repeat_idx[nb_frames-1];
    536               }
    537               /* Using the repeat mechanism almost always makes the
    538                   encoding smaller (or at least no larger).
    539                  However, there's one case where that might not be true: if
    540                   the last repeated long extension in the last frame was
    541                   previously the last extension, but using the repeat
    542                   mechanism makes that no longer true (because there are other
    543                   non-repeated extensions in earlier frames that must now be
    544                   coded after it), and coding its length requires more bytes
    545                   than the repeat mechanism saves.
    546                  This can only be true if its length is at least 255 bytes
    547                   (although sometimes it requires even more).
    548                  Currently we do not check for that, and just always use the
    549                   repeat mechanism if we can.
    550                  See git history for code that does the check. */
    551               /* Advance the repeat pointers. */
    552               for (g=f+1; g<nb_frames; g++)
    553               {
    554                  int j;
    555                  for (j=frame_repeat_idx[g]+1; j<frame_max_idx[g]
    556                   && extensions[j].frame != g; j++);
    557                  frame_repeat_idx[g] = j;
    558               }
    559               repeat_count++;
    560               /* Point the repeat pointer for this frame to the current
    561                   extension, so we know when to trigger the repeats. */
    562               frame_repeat_idx[f] = i;
    563            }
    564         }
    565      }
    566      for (i=frame_min_idx[f];i<frame_max_idx[f];i++)
    567      {
    568         if (extensions[i].frame == f)
    569         {
    570            /* Insert separator when needed. */
    571            if (f != curr_frame) {
    572               int diff = f - curr_frame;
    573               if (len-pos < 2)
    574                  return OPUS_BUFFER_TOO_SMALL;
    575               if (diff == 1) {
    576                  if (data) data[pos] = 0x02;
    577                  pos++;
    578               } else {
    579                  if (data) data[pos] = 0x03;
    580                  pos++;
    581                  if (data) data[pos] = diff;
    582                  pos++;
    583               }
    584               curr_frame = f;
    585            }
    586 
    587            pos = write_extension(data, len, pos, extensions + i,
    588             written == nb_extensions - 1);
    589            if (pos < 0) return pos;
    590            written++;
    591 
    592            if (repeat_count > 0 && frame_repeat_idx[f] == i) {
    593               int nb_repeated;
    594               int last;
    595               int g;
    596               /* Add the repeat indicator. */
    597               nb_repeated = repeat_count*(nb_frames - (f + 1));
    598               last = written + nb_repeated == nb_extensions
    599                || (last_long_idx < 0 && i+1 >= frame_max_idx[f]);
    600               if (len-pos < 1)
    601                  return OPUS_BUFFER_TOO_SMALL;
    602               if (data) data[pos] = 0x04 + !last;
    603               pos++;
    604               for (g=f+1;g<nb_frames;g++)
    605               {
    606                  int j;
    607                  for (j=frame_min_idx[g];j<frame_repeat_idx[g];j++)
    608                  {
    609                     if (extensions[j].frame == g)
    610                     {
    611                        pos = write_extension_payload(data, len, pos,
    612                         extensions + j, last && j == last_long_idx);
    613                        if (pos < 0) return pos;
    614                        written++;
    615                     }
    616                  }
    617                  frame_min_idx[g] = j;
    618               }
    619               if (last) curr_frame++;
    620            }
    621         }
    622      }
    623   }
    624   celt_assert(written == nb_extensions);
    625   /* If we need to pad, just prepend 0x01 bytes. Even better would be to fill the
    626      end with zeros, but that requires checking that turning the last extension into
    627      an L=1 case still fits. */
    628   if (pad && pos < len)
    629   {
    630      opus_int32 padding = len - pos;
    631      if (data) {
    632         OPUS_MOVE(data+padding, data, pos);
    633         for (i=0;i<padding;i++)
    634            data[i] = 0x01;
    635      }
    636      pos += padding;
    637   }
    638   return pos;
    639 }
    640 
    641 #if 0
    642 #include <stdio.h>
    643 int main()
    644 {
    645   opus_extension_data ext[] = {{2, 0, (const unsigned char *)"a", 1},
    646   {32, 10, (const unsigned char *)"DRED", 4},
    647   {33, 1, (const unsigned char *)"NOT DRED", 8},
    648   {3, 4, (const unsigned char *)NULL, 0}
    649   };
    650   opus_extension_data ext2[10];
    651   int i, len;
    652   int nb_ext = 10;
    653   unsigned char packet[10000];
    654   len = opus_packet_extensions_generate(packet, 32, ext, 4, 1);
    655   for (i=0;i<len;i++)
    656   {
    657      printf("%#04x ", packet[i]);
    658      if (i%16 == 15)
    659         printf("\n");
    660   }
    661   printf("\n");
    662   printf("count = %d\n", opus_packet_extensions_count(packet, len));
    663   opus_packet_extensions_parse(packet, len, ext2, &nb_ext);
    664   for (i=0;i<nb_ext;i++)
    665   {
    666      int j;
    667      printf("%d %d {", ext2[i].id, ext2[i].frame);
    668      for (j=0;j<ext2[i].len;j++) printf("%#04x ", ext2[i].data[j]);
    669      printf("} %d\n", ext2[i].len);
    670   }
    671 }
    672 #endif