LCOV - code coverage report
Current view: top level - media/libopus/src - repacketizer.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 175 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 14 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Copyright (c) 2011 Xiph.Org Foundation
       2             :    Written by Jean-Marc Valin */
       3             : /*
       4             :    Redistribution and use in source and binary forms, with or without
       5             :    modification, are permitted provided that the following conditions
       6             :    are met:
       7             : 
       8             :    - Redistributions of source code must retain the above copyright
       9             :    notice, this list of conditions and the following disclaimer.
      10             : 
      11             :    - Redistributions in binary form must reproduce the above copyright
      12             :    notice, this list of conditions and the following disclaimer in the
      13             :    documentation and/or other materials provided with the distribution.
      14             : 
      15             :    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      16             :    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      17             :    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      18             :    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
      19             :    OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
      20             :    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
      21             :    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
      22             :    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
      23             :    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
      24             :    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
      25             :    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      26             : */
      27             : 
      28             : #ifdef HAVE_CONFIG_H
      29             : #include "config.h"
      30             : #endif
      31             : 
      32             : #include "opus.h"
      33             : #include "opus_private.h"
      34             : #include "os_support.h"
      35             : 
      36             : 
      37           0 : int opus_repacketizer_get_size(void)
      38             : {
      39           0 :    return sizeof(OpusRepacketizer);
      40             : }
      41             : 
      42           0 : OpusRepacketizer *opus_repacketizer_init(OpusRepacketizer *rp)
      43             : {
      44           0 :    rp->nb_frames = 0;
      45           0 :    return rp;
      46             : }
      47             : 
      48           0 : OpusRepacketizer *opus_repacketizer_create(void)
      49             : {
      50             :    OpusRepacketizer *rp;
      51           0 :    rp=(OpusRepacketizer *)opus_alloc(opus_repacketizer_get_size());
      52           0 :    if(rp==NULL)return NULL;
      53           0 :    return opus_repacketizer_init(rp);
      54             : }
      55             : 
      56           0 : void opus_repacketizer_destroy(OpusRepacketizer *rp)
      57             : {
      58           0 :    opus_free(rp);
      59           0 : }
      60             : 
      61           0 : static int opus_repacketizer_cat_impl(OpusRepacketizer *rp, const unsigned char *data, opus_int32 len, int self_delimited)
      62             : {
      63             :    unsigned char tmp_toc;
      64             :    int curr_nb_frames,ret;
      65             :    /* Set of check ToC */
      66           0 :    if (len<1) return OPUS_INVALID_PACKET;
      67           0 :    if (rp->nb_frames == 0)
      68             :    {
      69           0 :       rp->toc = data[0];
      70           0 :       rp->framesize = opus_packet_get_samples_per_frame(data, 8000);
      71           0 :    } else if ((rp->toc&0xFC) != (data[0]&0xFC))
      72             :    {
      73             :       /*fprintf(stderr, "toc mismatch: 0x%x vs 0x%x\n", rp->toc, data[0]);*/
      74           0 :       return OPUS_INVALID_PACKET;
      75             :    }
      76           0 :    curr_nb_frames = opus_packet_get_nb_frames(data, len);
      77           0 :    if(curr_nb_frames<1) return OPUS_INVALID_PACKET;
      78             : 
      79             :    /* Check the 120 ms maximum packet size */
      80           0 :    if ((curr_nb_frames+rp->nb_frames)*rp->framesize > 960)
      81             :    {
      82           0 :       return OPUS_INVALID_PACKET;
      83             :    }
      84             : 
      85           0 :    ret=opus_packet_parse_impl(data, len, self_delimited, &tmp_toc, &rp->frames[rp->nb_frames], &rp->len[rp->nb_frames], NULL, NULL);
      86           0 :    if(ret<1)return ret;
      87             : 
      88           0 :    rp->nb_frames += curr_nb_frames;
      89           0 :    return OPUS_OK;
      90             : }
      91             : 
      92           0 : int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data, opus_int32 len)
      93             : {
      94           0 :    return opus_repacketizer_cat_impl(rp, data, len, 0);
      95             : }
      96             : 
      97           0 : int opus_repacketizer_get_nb_frames(OpusRepacketizer *rp)
      98             : {
      99           0 :    return rp->nb_frames;
     100             : }
     101             : 
     102           0 : opus_int32 opus_repacketizer_out_range_impl(OpusRepacketizer *rp, int begin, int end,
     103             :       unsigned char *data, opus_int32 maxlen, int self_delimited, int pad)
     104             : {
     105             :    int i, count;
     106             :    opus_int32 tot_size;
     107             :    opus_int16 *len;
     108             :    const unsigned char **frames;
     109             :    unsigned char * ptr;
     110             : 
     111           0 :    if (begin<0 || begin>=end || end>rp->nb_frames)
     112             :    {
     113             :       /*fprintf(stderr, "%d %d %d\n", begin, end, rp->nb_frames);*/
     114           0 :       return OPUS_BAD_ARG;
     115             :    }
     116           0 :    count = end-begin;
     117             : 
     118           0 :    len = rp->len+begin;
     119           0 :    frames = rp->frames+begin;
     120           0 :    if (self_delimited)
     121           0 :       tot_size = 1 + (len[count-1]>=252);
     122             :    else
     123           0 :       tot_size = 0;
     124             : 
     125           0 :    ptr = data;
     126           0 :    if (count==1)
     127             :    {
     128             :       /* Code 0 */
     129           0 :       tot_size += len[0]+1;
     130           0 :       if (tot_size > maxlen)
     131           0 :          return OPUS_BUFFER_TOO_SMALL;
     132           0 :       *ptr++ = rp->toc&0xFC;
     133           0 :    } else if (count==2)
     134             :    {
     135           0 :       if (len[1] == len[0])
     136             :       {
     137             :          /* Code 1 */
     138           0 :          tot_size += 2*len[0]+1;
     139           0 :          if (tot_size > maxlen)
     140           0 :             return OPUS_BUFFER_TOO_SMALL;
     141           0 :          *ptr++ = (rp->toc&0xFC) | 0x1;
     142             :       } else {
     143             :          /* Code 2 */
     144           0 :          tot_size += len[0]+len[1]+2+(len[0]>=252);
     145           0 :          if (tot_size > maxlen)
     146           0 :             return OPUS_BUFFER_TOO_SMALL;
     147           0 :          *ptr++ = (rp->toc&0xFC) | 0x2;
     148           0 :          ptr += encode_size(len[0], ptr);
     149             :       }
     150             :    }
     151           0 :    if (count > 2 || (pad && tot_size < maxlen))
     152             :    {
     153             :       /* Code 3 */
     154             :       int vbr;
     155           0 :       int pad_amount=0;
     156             : 
     157             :       /* Restart the process for the padding case */
     158           0 :       ptr = data;
     159           0 :       if (self_delimited)
     160           0 :          tot_size = 1 + (len[count-1]>=252);
     161             :       else
     162           0 :          tot_size = 0;
     163           0 :       vbr = 0;
     164           0 :       for (i=1;i<count;i++)
     165             :       {
     166           0 :          if (len[i] != len[0])
     167             :          {
     168           0 :             vbr=1;
     169           0 :             break;
     170             :          }
     171             :       }
     172           0 :       if (vbr)
     173             :       {
     174           0 :          tot_size += 2;
     175           0 :          for (i=0;i<count-1;i++)
     176           0 :             tot_size += 1 + (len[i]>=252) + len[i];
     177           0 :          tot_size += len[count-1];
     178             : 
     179           0 :          if (tot_size > maxlen)
     180           0 :             return OPUS_BUFFER_TOO_SMALL;
     181           0 :          *ptr++ = (rp->toc&0xFC) | 0x3;
     182           0 :          *ptr++ = count | 0x80;
     183             :       } else {
     184           0 :          tot_size += count*len[0]+2;
     185           0 :          if (tot_size > maxlen)
     186           0 :             return OPUS_BUFFER_TOO_SMALL;
     187           0 :          *ptr++ = (rp->toc&0xFC) | 0x3;
     188           0 :          *ptr++ = count;
     189             :       }
     190           0 :       pad_amount = pad ? (maxlen-tot_size) : 0;
     191           0 :       if (pad_amount != 0)
     192             :       {
     193             :          int nb_255s;
     194           0 :          data[1] |= 0x40;
     195           0 :          nb_255s = (pad_amount-1)/255;
     196           0 :          for (i=0;i<nb_255s;i++)
     197           0 :             *ptr++ = 255;
     198           0 :          *ptr++ = pad_amount-255*nb_255s-1;
     199           0 :          tot_size += pad_amount;
     200             :       }
     201           0 :       if (vbr)
     202             :       {
     203           0 :          for (i=0;i<count-1;i++)
     204           0 :             ptr += encode_size(len[i], ptr);
     205             :       }
     206             :    }
     207           0 :    if (self_delimited) {
     208           0 :       int sdlen = encode_size(len[count-1], ptr);
     209           0 :       ptr += sdlen;
     210             :    }
     211             :    /* Copy the actual data */
     212           0 :    for (i=0;i<count;i++)
     213             :    {
     214             :       /* Using OPUS_MOVE() instead of OPUS_COPY() in case we're doing in-place
     215             :          padding from opus_packet_pad or opus_packet_unpad(). */
     216           0 :       celt_assert(frames[i] + len[i] <= data || ptr <= frames[i]);
     217           0 :       OPUS_MOVE(ptr, frames[i], len[i]);
     218           0 :       ptr += len[i];
     219             :    }
     220           0 :    if (pad)
     221             :    {
     222             :       /* Fill padding with zeros. */
     223           0 :       while (ptr<data+maxlen)
     224           0 :          *ptr++=0;
     225             :    }
     226           0 :    return tot_size;
     227             : }
     228             : 
     229           0 : opus_int32 opus_repacketizer_out_range(OpusRepacketizer *rp, int begin, int end, unsigned char *data, opus_int32 maxlen)
     230             : {
     231           0 :    return opus_repacketizer_out_range_impl(rp, begin, end, data, maxlen, 0, 0);
     232             : }
     233             : 
     234           0 : opus_int32 opus_repacketizer_out(OpusRepacketizer *rp, unsigned char *data, opus_int32 maxlen)
     235             : {
     236           0 :    return opus_repacketizer_out_range_impl(rp, 0, rp->nb_frames, data, maxlen, 0, 0);
     237             : }
     238             : 
     239           0 : int opus_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len)
     240             : {
     241             :    OpusRepacketizer rp;
     242             :    opus_int32 ret;
     243           0 :    if (len < 1)
     244           0 :       return OPUS_BAD_ARG;
     245           0 :    if (len==new_len)
     246           0 :       return OPUS_OK;
     247           0 :    else if (len > new_len)
     248           0 :       return OPUS_BAD_ARG;
     249           0 :    opus_repacketizer_init(&rp);
     250             :    /* Moving payload to the end of the packet so we can do in-place padding */
     251           0 :    OPUS_MOVE(data+new_len-len, data, len);
     252           0 :    ret = opus_repacketizer_cat(&rp, data+new_len-len, len);
     253           0 :    if (ret != OPUS_OK)
     254           0 :       return ret;
     255           0 :    ret = opus_repacketizer_out_range_impl(&rp, 0, rp.nb_frames, data, new_len, 0, 1);
     256           0 :    if (ret > 0)
     257           0 :       return OPUS_OK;
     258             :    else
     259           0 :       return ret;
     260             : }
     261             : 
     262           0 : opus_int32 opus_packet_unpad(unsigned char *data, opus_int32 len)
     263             : {
     264             :    OpusRepacketizer rp;
     265             :    opus_int32 ret;
     266           0 :    if (len < 1)
     267           0 :       return OPUS_BAD_ARG;
     268           0 :    opus_repacketizer_init(&rp);
     269           0 :    ret = opus_repacketizer_cat(&rp, data, len);
     270           0 :    if (ret < 0)
     271           0 :       return ret;
     272           0 :    ret = opus_repacketizer_out_range_impl(&rp, 0, rp.nb_frames, data, len, 0, 0);
     273           0 :    celt_assert(ret > 0 && ret <= len);
     274           0 :    return ret;
     275             : }
     276             : 
     277           0 : int opus_multistream_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len, int nb_streams)
     278             : {
     279             :    int s;
     280             :    int count;
     281             :    unsigned char toc;
     282             :    opus_int16 size[48];
     283             :    opus_int32 packet_offset;
     284             :    opus_int32 amount;
     285             : 
     286           0 :    if (len < 1)
     287           0 :       return OPUS_BAD_ARG;
     288           0 :    if (len==new_len)
     289           0 :       return OPUS_OK;
     290           0 :    else if (len > new_len)
     291           0 :       return OPUS_BAD_ARG;
     292           0 :    amount = new_len - len;
     293             :    /* Seek to last stream */
     294           0 :    for (s=0;s<nb_streams-1;s++)
     295             :    {
     296           0 :       if (len<=0)
     297           0 :          return OPUS_INVALID_PACKET;
     298           0 :       count = opus_packet_parse_impl(data, len, 1, &toc, NULL,
     299             :                                      size, NULL, &packet_offset);
     300           0 :       if (count<0)
     301           0 :          return count;
     302           0 :       data += packet_offset;
     303           0 :       len -= packet_offset;
     304             :    }
     305           0 :    return opus_packet_pad(data, len, len+amount);
     306             : }
     307             : 
     308           0 : opus_int32 opus_multistream_packet_unpad(unsigned char *data, opus_int32 len, int nb_streams)
     309             : {
     310             :    int s;
     311             :    unsigned char toc;
     312             :    opus_int16 size[48];
     313             :    opus_int32 packet_offset;
     314             :    OpusRepacketizer rp;
     315             :    unsigned char *dst;
     316             :    opus_int32 dst_len;
     317             : 
     318           0 :    if (len < 1)
     319           0 :       return OPUS_BAD_ARG;
     320           0 :    dst = data;
     321           0 :    dst_len = 0;
     322             :    /* Unpad all frames */
     323           0 :    for (s=0;s<nb_streams;s++)
     324             :    {
     325             :       opus_int32 ret;
     326           0 :       int self_delimited = s!=nb_streams-1;
     327           0 :       if (len<=0)
     328           0 :          return OPUS_INVALID_PACKET;
     329           0 :       opus_repacketizer_init(&rp);
     330           0 :       ret = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL,
     331             :                                      size, NULL, &packet_offset);
     332           0 :       if (ret<0)
     333           0 :          return ret;
     334           0 :       ret = opus_repacketizer_cat_impl(&rp, data, packet_offset, self_delimited);
     335           0 :       if (ret < 0)
     336           0 :          return ret;
     337           0 :       ret = opus_repacketizer_out_range_impl(&rp, 0, rp.nb_frames, dst, len, self_delimited, 0);
     338           0 :       if (ret < 0)
     339           0 :          return ret;
     340             :       else
     341           0 :          dst_len += ret;
     342           0 :       dst += ret;
     343           0 :       data += packet_offset;
     344           0 :       len -= packet_offset;
     345             :    }
     346           0 :    return dst_len;
     347             : }
     348             : 

Generated by: LCOV version 1.13