Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: src/repacketizer.c

Issue 107243004: Updating Opus to release 1.1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/opus
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/opus_private.h ('k') | src/repacketizer_demo.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* Copyright (c) 2011 Xiph.Org Foundation 1 /* Copyright (c) 2011 Xiph.Org Foundation
2 Written by Jean-Marc Valin */ 2 Written by Jean-Marc Valin */
3 /* 3 /*
4 Redistribution and use in source and binary forms, with or without 4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions 5 modification, are permitted provided that the following conditions
6 are met: 6 are met:
7 7
8 - Redistributions of source code must retain the above copyright 8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer. 9 notice, this list of conditions and the following disclaimer.
10 10
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 rp=(OpusRepacketizer *)opus_alloc(opus_repacketizer_get_size()); 51 rp=(OpusRepacketizer *)opus_alloc(opus_repacketizer_get_size());
52 if(rp==NULL)return NULL; 52 if(rp==NULL)return NULL;
53 return opus_repacketizer_init(rp); 53 return opus_repacketizer_init(rp);
54 } 54 }
55 55
56 void opus_repacketizer_destroy(OpusRepacketizer *rp) 56 void opus_repacketizer_destroy(OpusRepacketizer *rp)
57 { 57 {
58 opus_free(rp); 58 opus_free(rp);
59 } 59 }
60 60
61 int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data, opus_ int32 len) 61 static int opus_repacketizer_cat_impl(OpusRepacketizer *rp, const unsigned char *data, opus_int32 len, int self_delimited)
62 { 62 {
63 unsigned char tmp_toc; 63 unsigned char tmp_toc;
64 int curr_nb_frames,ret; 64 int curr_nb_frames,ret;
65 /* Set of check ToC */ 65 /* Set of check ToC */
66 if (len<1) return OPUS_INVALID_PACKET; 66 if (len<1) return OPUS_INVALID_PACKET;
67 if (rp->nb_frames == 0) 67 if (rp->nb_frames == 0)
68 { 68 {
69 rp->toc = data[0]; 69 rp->toc = data[0];
70 rp->framesize = opus_packet_get_samples_per_frame(data, 8000); 70 rp->framesize = opus_packet_get_samples_per_frame(data, 8000);
71 } else if ((rp->toc&0xFC) != (data[0]&0xFC)) 71 } else if ((rp->toc&0xFC) != (data[0]&0xFC))
72 { 72 {
73 /*fprintf(stderr, "toc mismatch: 0x%x vs 0x%x\n", rp->toc, data[0]);*/ 73 /*fprintf(stderr, "toc mismatch: 0x%x vs 0x%x\n", rp->toc, data[0]);*/
74 return OPUS_INVALID_PACKET; 74 return OPUS_INVALID_PACKET;
75 } 75 }
76 curr_nb_frames = opus_packet_get_nb_frames(data, len); 76 curr_nb_frames = opus_packet_get_nb_frames(data, len);
77 if(curr_nb_frames<1) return OPUS_INVALID_PACKET; 77 if(curr_nb_frames<1) return OPUS_INVALID_PACKET;
78 78
79 /* Check the 120 ms maximum packet size */ 79 /* Check the 120 ms maximum packet size */
80 if ((curr_nb_frames+rp->nb_frames)*rp->framesize > 960) 80 if ((curr_nb_frames+rp->nb_frames)*rp->framesize > 960)
81 { 81 {
82 return OPUS_INVALID_PACKET; 82 return OPUS_INVALID_PACKET;
83 } 83 }
84 84
85 ret=opus_packet_parse(data, len, &tmp_toc, &rp->frames[rp->nb_frames], &rp->l en[rp->nb_frames], NULL); 85 ret=opus_packet_parse_impl(data, len, self_delimited, &tmp_toc, &rp->frames[r p->nb_frames], &rp->len[rp->nb_frames], NULL, NULL);
86 if(ret<1)return ret; 86 if(ret<1)return ret;
87 87
88 rp->nb_frames += curr_nb_frames; 88 rp->nb_frames += curr_nb_frames;
89 return OPUS_OK; 89 return OPUS_OK;
90 } 90 }
91 91
92 int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data, opus_ int32 len)
93 {
94 return opus_repacketizer_cat_impl(rp, data, len, 0);
95 }
96
92 int opus_repacketizer_get_nb_frames(OpusRepacketizer *rp) 97 int opus_repacketizer_get_nb_frames(OpusRepacketizer *rp)
93 { 98 {
94 return rp->nb_frames; 99 return rp->nb_frames;
95 } 100 }
96 101
97 opus_int32 opus_repacketizer_out_range_impl(OpusRepacketizer *rp, int begin, int end, unsigned char *data, opus_int32 maxlen, int self_delimited) 102 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)
98 { 104 {
99 int i, count; 105 int i, count;
100 opus_int32 tot_size; 106 opus_int32 tot_size;
101 opus_int16 *len; 107 opus_int16 *len;
102 const unsigned char **frames; 108 const unsigned char **frames;
109 unsigned char * ptr;
103 110
104 if (begin<0 || begin>=end || end>rp->nb_frames) 111 if (begin<0 || begin>=end || end>rp->nb_frames)
105 { 112 {
106 /*fprintf(stderr, "%d %d %d\n", begin, end, rp->nb_frames);*/ 113 /*fprintf(stderr, "%d %d %d\n", begin, end, rp->nb_frames);*/
107 return OPUS_BAD_ARG; 114 return OPUS_BAD_ARG;
108 } 115 }
109 count = end-begin; 116 count = end-begin;
110 117
111 len = rp->len+begin; 118 len = rp->len+begin;
112 frames = rp->frames+begin; 119 frames = rp->frames+begin;
113 if (self_delimited) 120 if (self_delimited)
114 tot_size = 1 + (len[count-1]>=252); 121 tot_size = 1 + (len[count-1]>=252);
115 else 122 else
116 tot_size = 0; 123 tot_size = 0;
117 124
118 switch (count) 125 ptr = data;
119 { 126 if (count==1)
120 case 1:
121 { 127 {
122 /* Code 0 */ 128 /* Code 0 */
123 tot_size += len[0]+1; 129 tot_size += len[0]+1;
124 if (tot_size > maxlen) 130 if (tot_size > maxlen)
125 return OPUS_BUFFER_TOO_SMALL; 131 return OPUS_BUFFER_TOO_SMALL;
126 *data++ = rp->toc&0xFC; 132 *ptr++ = rp->toc&0xFC;
127 } 133 } else if (count==2)
128 break;
129 case 2:
130 { 134 {
131 if (len[1] == len[0]) 135 if (len[1] == len[0])
132 { 136 {
133 /* Code 1 */ 137 /* Code 1 */
134 tot_size += 2*len[0]+1; 138 tot_size += 2*len[0]+1;
135 if (tot_size > maxlen) 139 if (tot_size > maxlen)
136 return OPUS_BUFFER_TOO_SMALL; 140 return OPUS_BUFFER_TOO_SMALL;
137 *data++ = (rp->toc&0xFC) | 0x1; 141 *ptr++ = (rp->toc&0xFC) | 0x1;
138 } else { 142 } else {
139 /* Code 2 */ 143 /* Code 2 */
140 tot_size += len[0]+len[1]+2+(len[0]>=252); 144 tot_size += len[0]+len[1]+2+(len[0]>=252);
141 if (tot_size > maxlen) 145 if (tot_size > maxlen)
142 return OPUS_BUFFER_TOO_SMALL; 146 return OPUS_BUFFER_TOO_SMALL;
143 *data++ = (rp->toc&0xFC) | 0x2; 147 *ptr++ = (rp->toc&0xFC) | 0x2;
144 data += encode_size(len[0], data); 148 ptr += encode_size(len[0], ptr);
145 } 149 }
146 } 150 }
147 break; 151 if (count > 2 || (pad && tot_size < maxlen))
148 default:
149 { 152 {
150 /* Code 3 */ 153 /* Code 3 */
151 int vbr; 154 int vbr;
155 int pad_amount=0;
152 156
157 /* Restart the process for the padding case */
158 ptr = data;
159 if (self_delimited)
160 tot_size = 1 + (len[count-1]>=252);
161 else
162 tot_size = 0;
153 vbr = 0; 163 vbr = 0;
154 for (i=1;i<count;i++) 164 for (i=1;i<count;i++)
155 { 165 {
156 if (len[i] != len[0]) 166 if (len[i] != len[0])
157 { 167 {
158 vbr=1; 168 vbr=1;
159 break; 169 break;
160 } 170 }
161 } 171 }
162 if (vbr) 172 if (vbr)
163 { 173 {
164 tot_size += 2; 174 tot_size += 2;
165 for (i=0;i<count-1;i++) 175 for (i=0;i<count-1;i++)
166 tot_size += 1 + (len[i]>=252) + len[i]; 176 tot_size += 1 + (len[i]>=252) + len[i];
167 tot_size += len[count-1]; 177 tot_size += len[count-1];
168 178
169 if (tot_size > maxlen) 179 if (tot_size > maxlen)
170 return OPUS_BUFFER_TOO_SMALL; 180 return OPUS_BUFFER_TOO_SMALL;
171 *data++ = (rp->toc&0xFC) | 0x3; 181 *ptr++ = (rp->toc&0xFC) | 0x3;
172 *data++ = count | 0x80; 182 *ptr++ = count | 0x80;
173 for (i=0;i<count-1;i++)
174 data += encode_size(len[i], data);
175 } else { 183 } else {
176 tot_size += count*len[0]+2; 184 tot_size += count*len[0]+2;
177 if (tot_size > maxlen) 185 if (tot_size > maxlen)
178 return OPUS_BUFFER_TOO_SMALL; 186 return OPUS_BUFFER_TOO_SMALL;
179 *data++ = (rp->toc&0xFC) | 0x3; 187 *ptr++ = (rp->toc&0xFC) | 0x3;
180 *data++ = count; 188 *ptr++ = count;
189 }
190 pad_amount = pad ? (maxlen-tot_size) : 0;
191 if (pad_amount != 0)
192 {
193 int nb_255s;
194 data[1] |= 0x40;
195 nb_255s = (pad_amount-1)/255;
196 for (i=0;i<nb_255s;i++)
197 *ptr++ = 255;
198 *ptr++ = pad_amount-255*nb_255s-1;
199 tot_size += pad_amount;
200 }
201 if (vbr)
202 {
203 for (i=0;i<count-1;i++)
204 ptr += encode_size(len[i], ptr);
181 } 205 }
182 } 206 }
183 break;
184 }
185 if (self_delimited) { 207 if (self_delimited) {
186 int sdlen = encode_size(len[count-1], data); 208 int sdlen = encode_size(len[count-1], ptr);
187 data += sdlen; 209 ptr += sdlen;
188 } 210 }
189 /* Copy the actual data */ 211 /* Copy the actual data */
190 for (i=0;i<count;i++) 212 for (i=0;i<count;i++)
191 { 213 {
192 OPUS_COPY(data, frames[i], len[i]); 214 /* Using OPUS_MOVE() instead of OPUS_COPY() in case we're doing in-place
193 data += len[i]; 215 padding from opus_packet_pad or opus_packet_unpad(). */
216 celt_assert(frames[i] + len[i] <= data || ptr <= frames[i]);
217 OPUS_MOVE(ptr, frames[i], len[i]);
218 ptr += len[i];
219 }
220 if (pad)
221 {
222 for (i=ptr-data;i<maxlen;i++)
223 data[i] = 0;
194 } 224 }
195 return tot_size; 225 return tot_size;
196 } 226 }
197 227
198 opus_int32 opus_repacketizer_out_range(OpusRepacketizer *rp, int begin, int end, unsigned char *data, opus_int32 maxlen) 228 opus_int32 opus_repacketizer_out_range(OpusRepacketizer *rp, int begin, int end, unsigned char *data, opus_int32 maxlen)
199 { 229 {
200 return opus_repacketizer_out_range_impl(rp, begin, end, data, maxlen, 0); 230 return opus_repacketizer_out_range_impl(rp, begin, end, data, maxlen, 0, 0);
201 } 231 }
202 232
203 opus_int32 opus_repacketizer_out(OpusRepacketizer *rp, unsigned char *data, opus _int32 maxlen) 233 opus_int32 opus_repacketizer_out(OpusRepacketizer *rp, unsigned char *data, opus _int32 maxlen)
204 { 234 {
205 return opus_repacketizer_out_range_impl(rp, 0, rp->nb_frames, data, maxlen, 0 ); 235 return opus_repacketizer_out_range_impl(rp, 0, rp->nb_frames, data, maxlen, 0 , 0);
206 } 236 }
207 237
238 int opus_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len)
239 {
240 OpusRepacketizer rp;
241 opus_int32 ret;
242 if (len < 1)
243 return OPUS_BAD_ARG;
244 if (len==new_len)
245 return OPUS_OK;
246 else if (len > new_len)
247 return OPUS_BAD_ARG;
248 opus_repacketizer_init(&rp);
249 /* Moving payload to the end of the packet so we can do in-place padding */
250 OPUS_MOVE(data+new_len-len, data, len);
251 opus_repacketizer_cat(&rp, data+new_len-len, len);
252 ret = opus_repacketizer_out_range_impl(&rp, 0, rp.nb_frames, data, new_len, 0 , 1);
253 if (ret > 0)
254 return OPUS_OK;
255 else
256 return ret;
257 }
208 258
259 opus_int32 opus_packet_unpad(unsigned char *data, opus_int32 len)
260 {
261 OpusRepacketizer rp;
262 opus_int32 ret;
263 if (len < 1)
264 return OPUS_BAD_ARG;
265 opus_repacketizer_init(&rp);
266 ret = opus_repacketizer_cat(&rp, data, len);
267 if (ret < 0)
268 return ret;
269 ret = opus_repacketizer_out_range_impl(&rp, 0, rp.nb_frames, data, len, 0, 0) ;
270 celt_assert(ret > 0 && ret <= len);
271 return ret;
272 }
273
274 int opus_multistream_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len, int nb_streams)
275 {
276 int s;
277 int count;
278 unsigned char toc;
279 opus_int16 size[48];
280 opus_int32 packet_offset;
281 opus_int32 amount;
282
283 if (len < 1)
284 return OPUS_BAD_ARG;
285 if (len==new_len)
286 return OPUS_OK;
287 else if (len > new_len)
288 return OPUS_BAD_ARG;
289 amount = new_len - len;
290 /* Seek to last stream */
291 for (s=0;s<nb_streams-1;s++)
292 {
293 if (len<=0)
294 return OPUS_INVALID_PACKET;
295 count = opus_packet_parse_impl(data, len, 1, &toc, NULL,
296 size, NULL, &packet_offset);
297 if (count<0)
298 return count;
299 data += packet_offset;
300 len -= packet_offset;
301 }
302 return opus_packet_pad(data, len, len+amount);
303 }
304
305 opus_int32 opus_multistream_packet_unpad(unsigned char *data, opus_int32 len, in t nb_streams)
306 {
307 int s;
308 unsigned char toc;
309 opus_int16 size[48];
310 opus_int32 packet_offset;
311 OpusRepacketizer rp;
312 unsigned char *dst;
313 opus_int32 dst_len;
314
315 if (len < 1)
316 return OPUS_BAD_ARG;
317 dst = data;
318 dst_len = 0;
319 /* Unpad all frames */
320 for (s=0;s<nb_streams;s++)
321 {
322 opus_int32 ret;
323 int self_delimited = s!=nb_streams-1;
324 if (len<=0)
325 return OPUS_INVALID_PACKET;
326 opus_repacketizer_init(&rp);
327 ret = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL,
328 size, NULL, &packet_offset);
329 if (ret<0)
330 return ret;
331 ret = opus_repacketizer_cat_impl(&rp, data, packet_offset, self_delimited) ;
332 if (ret < 0)
333 return ret;
334 ret = opus_repacketizer_out_range_impl(&rp, 0, rp.nb_frames, dst, len, sel f_delimited, 0);
335 if (ret < 0)
336 return ret;
337 else
338 dst_len += ret;
339 dst += ret;
340 data += packet_offset;
341 len -= packet_offset;
342 }
343 return dst_len;
344 }
345
OLDNEW
« no previous file with comments | « src/opus_private.h ('k') | src/repacketizer_demo.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698