opus_int32 opus_packet_unpad(unsigned char *data, opus_int32 len) { OpusRepacketizer rp; opus_int32 ret; if (len < 1) return OPUS_BAD_ARG; opus_repacketizer_init(&rp); ret = opus_repacketizer_cat(&rp, data, len); if (ret < 0) return ret; ret = opus_repacketizer_out_range_impl(&rp, 0, rp.nb_frames, data, len, 0, 0); celt_assert(ret > 0 && ret <= len); return ret; }
int opus_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len) { OpusRepacketizer rp; opus_int32 ret; if (len < 1) return OPUS_BAD_ARG; if (len==new_len) return OPUS_OK; else if (len > new_len) return OPUS_BAD_ARG; opus_repacketizer_init(&rp); /* Moving payload to the end of the packet so we can do in-place padding */ OPUS_MOVE(data+new_len-len, data, len); opus_repacketizer_cat(&rp, data+new_len-len, len); ret = opus_repacketizer_out_range_impl(&rp, 0, rp.nb_frames, data, new_len, 0, 1); if (ret > 0) return OPUS_OK; else return ret; }
opus_int32 opus_multistream_packet_unpad(unsigned char *data, opus_int32 len, int nb_streams) { int s; unsigned char toc; opus_int16 size[48]; opus_int32 packet_offset; OpusRepacketizer rp; unsigned char *dst; opus_int32 dst_len; if (len < 1) return OPUS_BAD_ARG; dst = data; dst_len = 0; /* Unpad all frames */ for (s=0;s<nb_streams;s++) { opus_int32 ret; int self_delimited = s!=nb_streams-1; if (len<=0) return OPUS_INVALID_PACKET; opus_repacketizer_init(&rp); ret = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL, size, NULL, &packet_offset); if (ret<0) return ret; ret = opus_repacketizer_cat_impl(&rp, data, packet_offset, self_delimited); if (ret < 0) return ret; ret = opus_repacketizer_out_range_impl(&rp, 0, rp.nb_frames, dst, len, self_delimited, 0); if (ret < 0) return ret; else dst_len += ret; dst += ret; data += packet_offset; len -= packet_offset; } return dst_len; }
opus_int32 opus_repacketizer_out(OpusRepacketizer *rp, unsigned char *data, opus_int32 maxlen) { return opus_repacketizer_out_range_impl(rp, 0, rp->nb_frames, data, maxlen, 0, 0); }
opus_int32 opus_repacketizer_out_range(OpusRepacketizer *rp, int begin, int end, unsigned char *data, opus_int32 maxlen) { return opus_repacketizer_out_range_impl(rp, begin, end, data, maxlen, 0, 0); }
int opus_multistream_encode_float( #endif OpusMSEncoder *st, const opus_val16 *pcm, int frame_size, unsigned char *data, opus_int32 max_data_bytes ) { int coupled_size; int mono_size; int s, i; char *ptr; int tot_size; VARDECL(opus_val16, buf); unsigned char tmp_data[MS_FRAME_TMP]; OpusRepacketizer rp; ALLOC_STACK; ALLOC(buf, 2*frame_size, opus_val16); ptr = (char*)st + align(sizeof(OpusMSEncoder)); coupled_size = opus_encoder_get_size(2); mono_size = opus_encoder_get_size(1); if (max_data_bytes < 4*st->layout.nb_streams-1) { RESTORE_STACK; return OPUS_BUFFER_TOO_SMALL; } /* Counting ToC */ tot_size = 0; for (s=0;s<st->layout.nb_streams;s++) { OpusEncoder *enc; int len; int curr_max; opus_repacketizer_init(&rp); enc = (OpusEncoder*)ptr; if (s < st->layout.nb_coupled_streams) { int left, right; left = get_left_channel(&st->layout, s, -1); right = get_right_channel(&st->layout, s, -1); for (i=0;i<frame_size;i++) { buf[2*i] = pcm[st->layout.nb_channels*i+left]; buf[2*i+1] = pcm[st->layout.nb_channels*i+right]; } ptr += align(coupled_size); } else { int chan = get_mono_channel(&st->layout, s, -1); for (i=0;i<frame_size;i++) buf[i] = pcm[st->layout.nb_channels*i+chan]; ptr += align(mono_size); } /* number of bytes left (+Toc) */ curr_max = max_data_bytes - tot_size; /* Reserve three bytes for the last stream and four for the others */ curr_max -= IMAX(0,4*(st->layout.nb_streams-s-1)-1); curr_max = IMIN(curr_max,MS_FRAME_TMP); len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max); if (len<0) { RESTORE_STACK; return len; } /* We need to use the repacketizer to add the self-delimiting lengths while taking into account the fact that the encoder can now return more than one frame at a time (e.g. 60 ms CELT-only) */ opus_repacketizer_cat(&rp, tmp_data, len); len = opus_repacketizer_out_range_impl(&rp, 0, opus_repacketizer_get_nb_frames(&rp), data, max_data_bytes-tot_size, s != st->layout.nb_streams-1); data += len; tot_size += len; } RESTORE_STACK; return tot_size; }