summaryrefslogtreecommitdiff
path: root/audio_codec/libraac/ra_depack_internal.c (plain)
blob: 4fcdd050f102853b208b258ad96c27bb9569995f
1#include <stdio.h>
2#include <string.h>
3#include <memory.h>
4#include "../include/helix_types.h"
5#include "../include/helix_result.h"
6#include "../include/pack_utils.h"
7#include "../include/string_utils.h"
8#include "../include/memory_utils.h"
9#include "../include/packet_defines.h"
10#include "../include/codec_defines.h"
11#include "../include/stream_hdr_utils.h"
12#include "ra_depack_internal.h"
13#include "../include/rasl.h"
14
15/* Defines */
16#define TIMESTAMP_GAP_FUDGE_FACTOR 1 /* Maximum non-loss, non-seek gap in ms between packets */
17#define INITIAL_FRAG_BUFFER_SIZE 2048 /* Initial size of frag buffer */
18#define RA_COPY_BUF 0
19
20void* ra_depacki_malloc(ra_depack_internal* pInt, UINT32 ulSize)
21{
22 void* pRet = HXNULL;
23
24 if (pInt && pInt->fpMalloc) {
25 pRet = pInt->fpMalloc(pInt->pUserMem, ulSize);
26 }
27
28 return pRet;
29}
30
31void ra_depacki_free(ra_depack_internal* pInt, void* pMem)
32{
33 if (pInt && pInt->fpFree) {
34 pInt->fpFree(pInt->pUserMem, pMem);
35 }
36}
37
38HX_RESULT ra_depacki_init(ra_depack_internal* pInt, rm_stream_header* hdr)
39{
40 HX_RESULT retVal = HXR_FAIL;
41
42 if (pInt && hdr) {
43 /* Initialize local variables */
44 UINT32 ulTmp = 0;
45 BYTE* pTmp = HXNULL;
46 UINT32 i = 0;
47 /* Check if we have a "HasRelativeTS" property - OK if we don't */
48 if (HX_SUCCEEDED(rm_stream_get_property_int(hdr, "TrackStartTime", &ulTmp))) {
49 pInt->bForceTrackStartTime = TRUE;
50 pInt->ulTrackStartTime = ulTmp;
51 }
52 /* Check if we have a "ZeroTimeOffset" property - OK if we don't */
53 if (HX_SUCCEEDED(rm_stream_get_property_int(hdr, "TrackEndTime", &ulTmp))) {
54 pInt->bForceTrackEndTime = TRUE;
55 pInt->ulTrackEndTime = ulTmp;
56 }
57 /* Check if we have an EndTime property */
58 if (HX_SUCCEEDED(rm_stream_get_property_int(hdr, "EndTime", &ulTmp))) {
59 pInt->bHasEndTime = TRUE;
60 pInt->ulEndTime = ulTmp;
61 }
62 /* Copy the stream duration */
63 pInt->ulStreamDuration = hdr->ulDuration;
64 /* If we have an end time, then clip the duration */
65 if (pInt->bHasEndTime &&
66 pInt->ulEndTime &&
67 pInt->ulStreamDuration > pInt->ulEndTime) {
68 pInt->ulStreamDuration = pInt->ulEndTime;
69 }
70 if (pInt->ulStreamDuration == 0) {
71 pInt->ulStreamDuration = 0x7fffffff;
72 }
73 /* Check if we have a "RMFF 1.0 Flags" property */
74 retVal = rm_stream_get_property_buf(hdr, "RMFF 1.0 Flags", &pTmp, &ulTmp);
75 if (retVal == HXR_OK) {
76 /* Parse the "RMFF 1.0 Flags" property */
77 retVal = ra_depacki_unpack_rule_map(pInt, &pInt->rule2Flag,
78 &pTmp, &ulTmp);
79 if (retVal == HXR_OK) {
80 /* Get the "OpaqueData" property */
81 retVal = rm_stream_get_property_buf(hdr, "OpaqueData", &pTmp, &ulTmp);
82 if (retVal == HXR_OK) {
83 /* Unpack the opaque data */
84 retVal = ra_depacki_unpack_opaque_data(pInt, pTmp, ulTmp);
85 }
86 }
87 }
88 }
89
90 return retVal;
91}
92
93HX_RESULT ra_depacki_unpack_rule_map(ra_depack_internal* pInt,
94 rm_rule_map* pMap,
95 BYTE** ppBuf,
96 UINT32* pulLen)
97{
98 HX_RESULT retVal = HXR_FAIL;
99
100 if (pInt) {
101 retVal = rm_unpack_rule_map(ppBuf, pulLen,
102 pInt->fpMalloc,
103 pInt->fpFree,
104 pInt->pUserMem,
105 pMap);
106 }
107
108 return retVal;
109}
110
111HX_RESULT ra_depacki_unpack_multistream_hdr(ra_depack_internal* pInt,
112 BYTE** ppBuf,
113 UINT32* pulLen)
114{
115 HX_RESULT retVal = HXR_FAIL;
116
117 if (pInt) {
118 retVal = rm_unpack_multistream_hdr(ppBuf, pulLen,
119 pInt->fpMalloc,
120 pInt->fpFree,
121 pInt->pUserMem,
122 &pInt->multiStreamHdr);
123 }
124
125 return retVal;
126}
127
128HX_RESULT ra_depacki_unpack_opaque_data(ra_depack_internal* pInt,
129 BYTE* pBuf,
130 UINT32 ulLen)
131{
132 HX_RESULT retVal = HXR_FAIL;
133
134 if (pInt && pBuf && ulLen >= 4) {
135 /* Initialize local variables */
136 UINT32 ulSize = 0;
137 UINT32 ulID = 0;
138 UINT32 i = 0;
139 UINT32 ulTmp = 0;
140 /*
141 * If the first four bytes are MLTI, then we
142 * know the opaque data contains a multistream header
143 * followed by several normal headers. So first we
144 * need to check the first four bytes.
145 */
146 ulID = rm_unpack32(&pBuf, &ulLen);
147 /* Now back up 4 bytes */
148 pBuf -= 4;
149 ulLen += 4;
150 /* Is this a multistream header? */
151 if (ulID == RM_MULTIHEADER_OBJECT) {
152 /* Unpack the multistream header */
153 retVal = ra_depacki_unpack_multistream_hdr(pInt, &pBuf, &ulLen);
154 if (retVal == HXR_OK) {
155 pInt->bStreamSwitchable = TRUE;
156 }
157 } else if (ulID == RA_FORMAT_ID) {
158 /* Single-rate stream */
159 pInt->multiStreamHdr.ulNumSubStreams = 1;
160 /* Clear the stream switchable flag */
161 pInt->bStreamSwitchable = FALSE;
162 /* Clear the return value */
163 retVal = HXR_OK;
164 }
165 /* Clean up any existing substream header array */
166 ra_depacki_cleanup_substream_hdr_array(pInt);
167 /* Set the return value */
168 retVal = HXR_FAIL;
169 /* Allocate space for substream header array */
170 ulSize = pInt->multiStreamHdr.ulNumSubStreams * sizeof(ra_substream_hdr);
171 pInt->pSubStreamHdr = (ra_substream_hdr*) ra_depacki_malloc(pInt, ulSize);
172 if (pInt->pSubStreamHdr) {
173 /* NULL out the memory */
174 memset(pInt->pSubStreamHdr, 0, ulSize);
175 /* Clear the return value */
176 retVal = HXR_OK;
177 /* Loop through and unpack each substream header */
178 for (i = 0; i < pInt->multiStreamHdr.ulNumSubStreams && retVal == HXR_OK; i++) {
179 /* Is this a multiheader? */
180 if (pInt->bStreamSwitchable) {
181 /*
182 * If this is a multistream header, then there
183 * is a 4-byte length in front of every substream header
184 */
185 if (ulLen >= 4) {
186 ulSize = rm_unpack32(&pBuf, &ulLen);
187 } else {
188 retVal = HXR_FAIL;
189 }
190 } else {
191 /*
192 * If this is not a multi-stream header, then
193 * the rest of the buffer is a single substream header
194 */
195 ulSize = ulLen;
196 }
197 /* Make sure we have enough parsing buffer */
198 if (ulLen >= ulSize) {
199 /* Now unpack an substream header */
200 retVal = ra_depacki_unpack_substream_hdr(pInt, pBuf, ulSize,
201 &pInt->pSubStreamHdr[i]);
202 if (retVal == HXR_OK) {
203 /* Get the substream header */
204 ra_substream_hdr* pHdr = &pInt->pSubStreamHdr[i];
205 /*
206 * If the interleaver ID is either VBRS of VBRF,
207 * then this is a VBR stream.
208 */
209 if (pHdr->ulInterleaverID == RA_INTERLEAVER_VBRS ||
210 pHdr->ulInterleaverID == RA_INTERLEAVER_VBRF) {
211 pHdr->bIsVBR = TRUE;
212 }
213 /* Compute the number of codec frames per superblock */
214 if (pHdr->ulCodecFrameSize) {
215 pHdr->ulNumCodecFrames = pHdr->ulInterleaveBlockSize *
216 pHdr->ulInterleaveFactor /
217 pHdr->ulCodecFrameSize;
218 }
219 /* Compute the ms per block */
220 if (pHdr->ulBytesPerMin) {
221 pHdr->dBlockDuration = ((double) pHdr->ulInterleaveBlockSize) *
222 60000.0 /
223 ((double) pHdr->ulBytesPerMin);
224 }
225 /* Compute the superblock size and time */
226 pHdr->ulSuperBlockSize = pHdr->ulInterleaveBlockSize *
227 pHdr->ulInterleaveFactor;
228 pHdr->ulSuperBlockTime = (UINT32)(pHdr->dBlockDuration *
229 ((double) pHdr->ulInterleaveFactor));
230 /* Is this stream VBR? */
231 if (pHdr->bIsVBR) {
232 /* Init the last sent block end time */
233 pHdr->ulLastSentEndTime = 0;
234 /*
235 * Init the frag buffer members. The frag buffer
236 * willl be set up the first time it is needed.
237 */
238 pHdr->pFragBuffer = HXNULL;
239 pHdr->ulFragBufferSize = 0;
240 pHdr->ulFragBufferOffset = 0;
241 pHdr->ulFragBufferTime = 0;
242 } else {
243 /* Set the return value */
244 retVal = HXR_OUTOFMEMORY;
245 /* Set the superblock keyframe time */
246 pHdr->bHasKeyTime = FALSE;
247 pHdr->ulKeyTime = 0;
248 /* Allocate the interleaved buffer */
249 pHdr->pIBuffer = (BYTE*) ra_depacki_malloc(pInt, pHdr->ulSuperBlockSize);
250 if (pHdr->pIBuffer) {
251 /* Zero out the buffer */
252 memset(pHdr->pIBuffer, 0, pHdr->ulSuperBlockSize);
253 /* Allocate the de-interleaved buffer */
254 pHdr->pDBuffer = (BYTE*) ra_depacki_malloc(pInt, pHdr->ulSuperBlockSize);
255 if (pHdr->pDBuffer) {
256 /* Zero out the buffer */
257 memset(pHdr->pDBuffer, 0, pHdr->ulSuperBlockSize);
258 /* Allocate the interleaved flags */
259 ulTmp = pHdr->ulInterleaveFactor * sizeof(UINT32);
260 pHdr->pIPresentFlags = (UINT32*) ra_depacki_malloc(pInt, ulTmp);
261 if (pHdr->pIPresentFlags) {
262 /* Zero out the flags */
263 memset(pHdr->pIPresentFlags, 0, ulTmp);
264 /* Allocate the de-interleaved flags */
265 pHdr->pDPresentFlags = (UINT32*) ra_depacki_malloc(pInt, ulTmp);
266 if (pHdr->pDPresentFlags) {
267 /* Null out the memory */
268 memset(pHdr->pDPresentFlags, 0, ulTmp);
269 /* Clear the return value */
270 retVal = HXR_OK;
271 /* If this is GENR interleaving, then init the tables */
272 if (pHdr->ulInterleaverID == RA_INTERLEAVER_GENR) {
273 retVal = ra_depacki_init_genr(pInt, i);
274 }
275 }
276 }
277 }
278 }
279 }
280 /* Update the buffer cursors */
281 pBuf += ulSize;
282 ulLen -= ulSize;
283 }
284 } else {
285 retVal = HXR_FAIL;
286 }
287 }
288 }
289 }
290
291 return retVal;
292}
293
294void ra_depacki_cleanup_substream_hdr(ra_depack_internal* pInt,
295 ra_substream_hdr* hdr)
296{
297 if (pInt && hdr) {
298 if (hdr->pulInterleavePattern) {
299 ra_depacki_free(pInt, hdr->pulInterleavePattern);
300 hdr->pulInterleavePattern = HXNULL;
301 }
302 if (hdr->pOpaqueData) {
303 ra_depacki_free(pInt, hdr->pOpaqueData);
304 hdr->pOpaqueData = HXNULL;
305 }
306 if (hdr->pFragBuffer) {
307 ra_depacki_free(pInt, hdr->pFragBuffer);
308 hdr->pFragBuffer = HXNULL;
309 }
310 if (hdr->pIBuffer) {
311 ra_depacki_free(pInt, hdr->pIBuffer);
312 hdr->pIBuffer = HXNULL;
313 }
314 if (hdr->pDBuffer) {
315 ra_depacki_free(pInt, hdr->pDBuffer);
316 hdr->pDBuffer = HXNULL;
317 }
318 if (hdr->pIPresentFlags) {
319 ra_depacki_free(pInt, hdr->pIPresentFlags);
320 hdr->pIPresentFlags = HXNULL;
321 }
322 if (hdr->pDPresentFlags) {
323 ra_depacki_free(pInt, hdr->pDPresentFlags);
324 hdr->pDPresentFlags = HXNULL;
325 }
326 if (hdr->pulGENRPattern) {
327 ra_depacki_free(pInt, hdr->pulGENRPattern);
328 hdr->pulGENRPattern = HXNULL;
329 }
330 if (hdr->pulGENRBlockNum) {
331 ra_depacki_free(pInt, hdr->pulGENRBlockNum);
332 hdr->pulGENRBlockNum = HXNULL;
333 }
334 if (hdr->pulGENRBlockOffset) {
335 ra_depacki_free(pInt, hdr->pulGENRBlockOffset);
336 hdr->pulGENRBlockOffset = HXNULL;
337 }
338 }
339}
340
341void ra_depacki_cleanup_substream_hdr_array(ra_depack_internal* pInt)
342{
343 if (pInt && pInt->pSubStreamHdr) {
344 UINT32 i = 0;
345 for (i = 0; i < pInt->multiStreamHdr.ulNumSubStreams; i++) {
346 ra_depacki_cleanup_substream_hdr(pInt, &pInt->pSubStreamHdr[i]);
347 }
348 /* Free the header array */
349 ra_depacki_free(pInt, pInt->pSubStreamHdr);
350 /* NULL out the pointer */
351 pInt->pSubStreamHdr = HXNULL;
352 }
353}
354
355HX_RESULT ra_depacki_unpack_substream_hdr(ra_depack_internal* pInt,
356 BYTE* pBuf,
357 UINT32 ulLen,
358 ra_substream_hdr* pHdr)
359{
360 HX_RESULT retVal = HXR_FAIL;
361
362 if (pInt && pBuf && ulLen >= 6 && pHdr) {
363 UINT32 ulID = 0;
364 UINT16 usVersion = 0;
365 /* Clean up any existing header info */
366 ra_depacki_cleanup_substream_hdr(pInt, pHdr);
367 /* Read the ID and the RAFormat version */
368 ulID = rm_unpack32(&pBuf, &ulLen);
369 usVersion = rm_unpack16(&pBuf, &ulLen);
370 /* Sanity check on ID */
371 if (ulID == RA_FORMAT_ID) {
372 /* Switch based on RAFormat version */
373 switch (usVersion) {
374 case 3:
375 retVal = ra_depacki_unpack_raformat3(pInt, pBuf, ulLen, pHdr);
376 break;
377 case 4:
378 retVal = ra_depacki_unpack_raformat4(pInt, pBuf, ulLen, pHdr);
379 break;
380 case 5:
381 retVal = ra_depacki_unpack_raformat5(pInt, pBuf, ulLen, pHdr);
382 break;
383 }
384 }
385 }
386
387 return retVal;
388}
389
390HX_RESULT ra_depacki_unpack_raformat3(ra_depack_internal* pInt,
391 BYTE* pBuf,
392 UINT32 ulLen,
393 ra_substream_hdr* pHdr)
394{
395 return HXR_NOTIMPL;
396}
397
398HX_RESULT ra_depacki_unpack_raformat4(ra_depack_internal* pInt,
399 BYTE* pBuf,
400 UINT32 ulLen,
401 ra_substream_hdr* pHdr)
402{
403 HX_RESULT retVal = HXR_FAIL;
404
405 if (pInt && pBuf && ulLen >= 63 && pHdr) {
406 /* Init local variables */
407 UINT32 ulSize = 0;
408 UINT32 i = 0;
409 /* Skip first 10 bytes */
410 pBuf += 10;
411 ulLen -= 10;
412 /* Read the version and revision */
413 pHdr->usRAFormatVersion = rm_unpack16(&pBuf, &ulLen);
414 pHdr->usRAFormatRevision = rm_unpack16(&pBuf, &ulLen);
415 /* Sanity check */
416 if (pHdr->usRAFormatVersion == 4 &&
417 pHdr->usRAFormatRevision == 0) {
418 pHdr->usHeaderBytes = rm_unpack16(&pBuf, &ulLen);
419 pHdr->usFlavorIndex = rm_unpack16(&pBuf, &ulLen);
420 pHdr->ulGranularity = rm_unpack32(&pBuf, &ulLen);
421 pHdr->ulTotalBytes = rm_unpack32(&pBuf, &ulLen);
422 pHdr->ulBytesPerMin = rm_unpack32(&pBuf, &ulLen);
423 pHdr->ulBytesPerMin2 = rm_unpack32(&pBuf, &ulLen);
424 pHdr->ulInterleaveFactor = rm_unpack16(&pBuf, &ulLen);
425 pHdr->ulInterleaveBlockSize = rm_unpack16(&pBuf, &ulLen);
426 pHdr->ulUserData = rm_unpack32(&pBuf, &ulLen);
427 pHdr->ulSampleRate = rm_unpack32(&pBuf, &ulLen);
428 pHdr->ulSampleRate >>= 16;
429 pHdr->ulSampleSize = rm_unpack16(&pBuf, &ulLen);
430 pHdr->ulChannels = rm_unpack16(&pBuf, &ulLen);
431 pHdr->ulInterleaverID = rm_unpack32_from_byte_string(&pBuf, &ulLen);
432 pHdr->ulCodecID = rm_unpack32_from_byte_string(&pBuf, &ulLen);
433 pHdr->bIsInterleaved = rm_unpack8(&pBuf, &ulLen);
434 pHdr->bCopyByte = rm_unpack8(&pBuf, &ulLen);
435 pHdr->ucStreamType = rm_unpack8(&pBuf, &ulLen);
436 /*
437 * If the bIsInterleaved flag says we are
438 * not interleaved, then make sure the
439 * interleaverID is set to no interleaver.
440 */
441 if (!pHdr->bIsInterleaved) {
442 pHdr->ulInterleaverID = RA_NO_INTERLEAVER;
443 }
444 /* If the interleave factor is 0, make it 1. */
445 if (!pHdr->ulInterleaveFactor) {
446 pHdr->ulInterleaveFactor = 1;
447 }
448 /* Clear the return value */
449 retVal = HXR_OK;
450 }
451 }
452
453 return retVal;
454}
455
456HX_RESULT ra_depacki_unpack_raformat5(ra_depack_internal* pInt,
457 BYTE* pBuf,
458 UINT32 ulLen,
459 ra_substream_hdr* pHdr)
460{
461 HX_RESULT retVal = HXR_FAIL;
462
463 if (pInt && pBuf && ulLen >= 68 && pHdr) {
464 /* Init local variables */
465 UINT32 ulSize = 0;
466 UINT32 i = 0;
467 /* Skip first 10 bytes */
468 pBuf += 10;
469 ulLen -= 10;
470 /* Read the version and revision */
471 pHdr->usRAFormatVersion = rm_unpack16(&pBuf, &ulLen);
472 pHdr->usRAFormatRevision = rm_unpack16(&pBuf, &ulLen);
473 /* Sanity check */
474 if (pHdr->usRAFormatVersion == 5 &&
475 pHdr->usRAFormatRevision == 0) {
476 pHdr->usHeaderBytes = rm_unpack16(&pBuf, &ulLen);
477 pHdr->usFlavorIndex = rm_unpack16(&pBuf, &ulLen);
478 pHdr->ulGranularity = rm_unpack32(&pBuf, &ulLen);
479 pHdr->ulTotalBytes = rm_unpack32(&pBuf, &ulLen);
480 pHdr->ulBytesPerMin = rm_unpack32(&pBuf, &ulLen);
481 pHdr->ulBytesPerMin2 = rm_unpack32(&pBuf, &ulLen);
482 pHdr->ulInterleaveFactor = rm_unpack16(&pBuf, &ulLen);
483 pHdr->ulInterleaveBlockSize = rm_unpack16(&pBuf, &ulLen);
484 pHdr->ulCodecFrameSize = rm_unpack16(&pBuf, &ulLen);
485 pHdr->ulUserData = rm_unpack32(&pBuf, &ulLen);
486 pHdr->ulSampleRate = rm_unpack32(&pBuf, &ulLen);
487 pHdr->ulSampleRate >>= 16;
488 pHdr->ulActualSampleRate = rm_unpack32(&pBuf, &ulLen);
489 pHdr->ulActualSampleRate >>= 16;
490 pHdr->ulSampleSize = rm_unpack16(&pBuf, &ulLen);
491 pHdr->ulChannels = rm_unpack16(&pBuf, &ulLen);
492 pHdr->ulInterleaverID = rm_unpack32(&pBuf, &ulLen);
493 pHdr->ulCodecID = rm_unpack32(&pBuf, &ulLen);
494 pHdr->bIsInterleaved = rm_unpack8(&pBuf, &ulLen);
495 pHdr->bCopyByte = rm_unpack8(&pBuf, &ulLen);
496 pHdr->ucStreamType = rm_unpack8(&pBuf, &ulLen);
497 pHdr->ucScatterType = rm_unpack8(&pBuf, &ulLen);
498 pHdr->ulNumCodecFrames = pHdr->ulInterleaveFactor *
499 pHdr->ulInterleaveBlockSize /
500 pHdr->ulCodecFrameSize;
501 /* Clear the return value */
502 retVal = HXR_OK;
503 /*
504 * If ucScatterType is non-zero, then we have
505 * to read in an interleave pattern.
506 */
507 if (pHdr->ucScatterType) {
508 /* Set the return value */
509 retVal = HXR_FAIL;
510 /* Allocate space for the interleave pattern */
511 ulSize = pHdr->ulNumCodecFrames * sizeof(UINT32);
512 pHdr->pulInterleavePattern = ra_depacki_malloc(pInt, ulSize);
513 if (pHdr->pulInterleavePattern) {
514 /* NULL out all the memory */
515 memset(pHdr->pulInterleavePattern, 0, ulSize);
516 /* Make sure we have enough parsing buffer left */
517 if (ulLen >= ulSize) {
518 /* Read in the interleave pattern */
519 for (i = 0; i < pHdr->ulNumCodecFrames; i++) {
520 pHdr->pulInterleavePattern[i] = rm_unpack16(&pBuf, &ulLen);
521 }
522 /* Clear the return value */
523 retVal = HXR_OK;
524 }
525 }
526 }
527 if (retVal == HXR_OK) {
528 /* Set the return value */
529 retVal = HXR_FAIL;
530 /* Make sure we have four bytes */
531 if (ulLen >= 4) {
532 /* Read in the opaque data size */
533 pHdr->ulOpaqueDataSize = rm_unpack32(&pBuf, &ulLen);
534 /* Make sure we have this much parsing space left */
535 if ((ulLen >= pHdr->ulOpaqueDataSize) && (pHdr->ulOpaqueDataSize > 0)) {
536 /* Allocate the buffer */
537 pHdr->pOpaqueData = ra_depacki_malloc(pInt, pHdr->ulOpaqueDataSize);
538 if (pHdr->pOpaqueData) {
539 /* Copy the opaque data */
540 memcpy(pHdr->pOpaqueData, pBuf, pHdr->ulOpaqueDataSize);
541 /* Clear the return value */
542 retVal = HXR_OK;
543 /*
544 * If the bIsInterleaved flag says we are
545 * not interleaved, then make sure the
546 * interleaverID is set to no interleaver.
547 */
548 if (!pHdr->bIsInterleaved) {
549 pHdr->ulInterleaverID = RA_NO_INTERLEAVER;
550 }
551 /* If the interleave factor is 0, make it 1. */
552 if (!pHdr->ulInterleaveFactor) {
553 pHdr->ulInterleaveFactor = 1;
554 }
555 }
556 } else if (pHdr->ulOpaqueDataSize == 0) {
557 retVal = HXR_OK;
558 }
559 }
560 }
561 }
562 }
563
564 return retVal;
565}
566
567HX_RESULT ra_depacki_get_format_info(ra_depack_internal* pInt,
568 UINT32 ulSubStream,
569 ra_format_info* pInfo)
570{
571 HX_RESULT retVal = HXR_FAIL;
572
573 if (pInt && pInfo && pInt->pSubStreamHdr &&
574 ulSubStream < pInt->multiStreamHdr.ulNumSubStreams) {
575 /* Init local variables */
576 ra_substream_hdr* pHdr = &pInt->pSubStreamHdr[ulSubStream];
577 if (pHdr) {
578 /* Clean up any existing format info */
579 ra_depacki_cleanup_format_info(pInt, pInfo);
580 /* Assign members */
581 pInfo->ulSampleRate = pHdr->ulSampleRate;
582 pInfo->ulActualRate = pHdr->ulActualSampleRate;
583 pInfo->usBitsPerSample = (UINT16) pHdr->ulSampleSize;
584 pInfo->usNumChannels = (UINT16) pHdr->ulChannels;
585 pInfo->usAudioQuality = 100;
586 pInfo->usFlavorIndex = pHdr->usFlavorIndex;
587 pInfo->ulBitsPerFrame = pHdr->ulCodecFrameSize;
588 pInfo->ulGranularity = pHdr->ulGranularity;
589 pInfo->ulOpaqueDataSize = pHdr->ulOpaqueDataSize;
590 /* Copy the opaque data buffer */
591 pInfo->pOpaqueData = copy_buffer(pInt->pUserMem,
592 pInt->fpMalloc,
593 pHdr->pOpaqueData,
594 pHdr->ulOpaqueDataSize);
595 if (!pInfo->ulOpaqueDataSize || pInfo->pOpaqueData) {
596 /* Clear the return value */
597 retVal = HXR_OK;
598 }
599 }
600 }
601
602 return retVal;
603}
604
605void ra_depacki_cleanup_format_info(ra_depack_internal* pInt,
606 ra_format_info* pInfo)
607{
608 if (pInt && pInfo && pInfo->pOpaqueData) {
609 ra_depacki_free(pInt, pInfo->pOpaqueData);
610 pInfo->pOpaqueData = HXNULL;
611 }
612}
613
614UINT32 ra_depacki_rule_to_flags(ra_depack_internal* pInt, UINT32 ulRule)
615{
616 UINT32 ulRet = 0;
617
618 if (pInt && pInt->rule2Flag.pulMap &&
619 ulRule < pInt->rule2Flag.ulNumRules) {
620 ulRet = pInt->rule2Flag.pulMap[ulRule];
621 }
622
623 return ulRet;
624}
625
626HXBOOL ra_depacki_is_keyframe_rule(ra_depack_internal* pInt, UINT32 ulRule)
627{
628 UINT32 ulFlag = ra_depacki_rule_to_flags(pInt, ulRule);
629 return (ulFlag & HX_KEYFRAME_FLAG ? TRUE : FALSE);
630}
631
632UINT32 ra_depacki_rule_to_substream(ra_depack_internal* pInt, UINT32 ulRule)
633{
634 UINT32 ulRet = 0;
635
636 if (pInt && pInt->multiStreamHdr.rule2SubStream.pulMap &&
637 ulRule < pInt->multiStreamHdr.rule2SubStream.ulNumRules) {
638 ulRet = pInt->multiStreamHdr.rule2SubStream.pulMap[ulRule];
639 }
640
641 return ulRet;
642}
643
644HX_RESULT ra_depacki_add_packet(ra_depack_internal* pInt,
645 rm_packet* pPacket)
646{
647 HX_RESULT retVal = HXR_FAIL;
648
649 if (pInt && pPacket) {
650 /* Init local variables */
651 UINT32 i = 0;
652 /* Was this packet lost? */
653 if (!pPacket->ucLost) {
654 /* This packet was not lost, so we can look up the substream. */
655 UINT32 ulSubStream = ra_depacki_rule_to_substream(pInt, pPacket->ucASMRule);
656 /* Sanity check */
657 if (pInt->pSubStreamHdr &&
658 ulSubStream < pInt->multiStreamHdr.ulNumSubStreams) {
659 /* Is this substream VBR? */
660 if (pInt->pSubStreamHdr[ulSubStream].bIsVBR) {
661 /* Add the VBR packet */
662 retVal = ra_depacki_add_vbr_packet(pInt, ulSubStream, pPacket);
663 } else {
664 /* Add the non-VBR packet */
665 retVal = ra_depacki_add_non_vbr_packet(pInt, ulSubStream, pPacket);
666 }
667 }
668 } else {
669 /* Are we multistream or single-stream? */
670 if (pInt->bStreamSwitchable) {
671 /*
672 * We are multi-stream. Therefore, we don't know which
673 * substream this packet came from. So we simply set the
674 * flag saying some loss happened in each substream.
675 */
676 for (i = 0; i < pInt->multiStreamHdr.ulNumSubStreams; i++) {
677 pInt->pSubStreamHdr[i].bLossOccurred = TRUE;
678 }
679 /* Clear the return value */
680 retVal = HXR_OK;
681 } else {
682 /*
683 * We are single substream, so we just pass the
684 * lost packet on. It has to be substream 0, of course.
685 */
686 if (pInt->pSubStreamHdr &&
687 pInt->multiStreamHdr.ulNumSubStreams) {
688 /* Is the single substream VBR? */
689 if (pInt->pSubStreamHdr[0].bIsVBR) {
690 retVal = ra_depacki_add_vbr_packet(pInt, 0, pPacket);
691 } else {
692 retVal = ra_depacki_add_non_vbr_packet(pInt, 0, pPacket);
693 }
694 }
695 }
696 }
697 }
698
699 return retVal;
700}
701
702HX_RESULT ra_depacki_add_vbr_packet(ra_depack_internal* pInt,
703 UINT32 ulSubStream,
704 rm_packet* pPacket)
705{
706 HX_RESULT retVal = HXR_FAIL;
707
708 if (pInt && pPacket) {
709 /* Is the packet lost? */
710 if (!pPacket->ucLost) {
711 /* Packet was not lost */
712 if (pInt->pSubStreamHdr &&
713 ulSubStream < pInt->multiStreamHdr.ulNumSubStreams) {
714 /* Get the substream header */
715 ra_substream_hdr* pHdr = &pInt->pSubStreamHdr[ulSubStream];
716 /* Init local variables */
717 UINT32 ulNumAU = 0;
718 HXBOOL bFrag = FALSE;
719 UINT32 ulAUSize = 0;
720 UINT32 ulAUFragSize = 0;
721 UINT32 i = 0;
722 /* Parse this VBR packet */
723 retVal = ra_depacki_parse_vbr_packet(pInt, pPacket, &ulNumAU, &bFrag,
724 &ulAUSize, &ulAUFragSize);
725 if (retVal == HXR_OK) {
726 /*
727 * Are we within the tolerance? We expect to
728 * be if we didn't seek. Otherwise, we had loss.
729 */
730 if (pPacket->ulTime > pHdr->ulLastSentEndTime + TIMESTAMP_GAP_FUDGE_FACTOR &&
731 !pHdr->bSeeked) {
732 /* We need to send some loss packets */
733 retVal = ra_depacki_generate_and_send_loss(pInt,
734 ulSubStream,
735 pHdr->ulLastSentEndTime,
736 pPacket->ulTime);
737 if (retVal == HXR_OK) {
738 pHdr->ulLastSentEndTime = pPacket->ulTime;
739 }
740 }
741 /* Have we just seeked? */
742 if (pHdr->bSeeked) {
743 /* Clear any remaining fragment */
744 ra_depacki_clear_frag_buffer(pInt, pHdr);
745 /* Set the last sent time to this time */
746 pHdr->ulLastSentEndTime = pPacket->ulTime;
747 /* Clear the seeked flag */
748 pHdr->bSeeked = FALSE;
749 }
750 /* Does this packet hold a fragmented AU? */
751 if (bFrag) {
752 /* Handle the fragmented packet */
753 retVal = ra_depacki_handle_frag_packet(pInt, ulSubStream, pPacket,
754 ulAUSize, ulAUFragSize);
755 } else {
756 /* Handle the non-fragmented packet */
757 retVal = ra_depacki_handle_nonfrag_packet(pInt, ulSubStream,
758 pPacket, ulNumAU);
759 }
760 }
761 }
762 } else {
763 /* Packet is lost - not an error */
764 retVal = HXR_OK;
765 }
766 }
767
768 return retVal;
769}
770
771HX_RESULT ra_depacki_add_non_vbr_packet(ra_depack_internal* pInt,
772 UINT32 ulSubStream,
773 rm_packet* pPacket)
774{
775 HX_RESULT retVal = HXR_FAIL;
776
777 if (pInt && pPacket && pInt->pSubStreamHdr &&
778 ulSubStream < pInt->multiStreamHdr.ulNumSubStreams) {
779 /* Init local variables */
780 HXBOOL bKey = FALSE;
781 HXDOUBLE dTimeDiff = 0.0;
782 HXDOUBLE dBlockNum = 0;
783 UINT32 ulBlockNum = 0;
784 HXDOUBLE dTSOffset = 0.0;
785 UINT32 ulTSOffset = 0;
786 UINT32 ulPacketTime = pPacket->ulTime;
787 /* Get the substream header */
788 ra_substream_hdr* pHdr = &pInt->pSubStreamHdr[ulSubStream];
789 /* Is the packet lost? */
790 if (!pPacket->ucLost) {
791 /* Is this a keyframe packet? */
792 bKey = ra_depacki_is_keyframe_rule(pInt, pPacket->ucASMRule);
793 /*
794 * We need to determine the index of this block
795 * in this superblock. We will do this by knowing
796 * the timestamp of this packet (block), the timestamp
797 * of the key block in this superblock, and the block
798 * duration. First we make sure we have a key block time.
799 */
800 if (bKey && !pHdr->bHasKeyTime) {
801 /* We note the timestamp of this key block */
802 pHdr->ulKeyTime = pPacket->ulTime;
803 /* Set the flag saying we have a key time */
804 pHdr->bHasKeyTime = TRUE;
805 }
806 /* Now we should have a key time */
807 if (pHdr->bHasKeyTime && ulPacketTime >= pHdr->ulKeyTime) {
808 /*
809 * Have we yet determined whether or
810 * not we need to adjust timestamps?
811 */
812 if (!pHdr->bKnowIfAdjustNeeded) {
813 /*
814 * If the last packet was not lost and was a
815 * keyframe and this packet is not a keyframe
816 * and the timestamps are the same, then we need
817 * to adjust timestamps.
818 */
819 if (pHdr->bHasLastPacket &&
820 !pHdr->lastPacket.ucLost &&
821 !bKey) {
822 /* Is this timestamp the same as the last packets? */
823 if (ulPacketTime == pHdr->lastPacket.ulTime) {
824 pHdr->bAdjustTimestamps = TRUE;
825 } else {
826 pHdr->bAdjustTimestamps = FALSE;
827 }
828 /* Now we know */
829 pHdr->bKnowIfAdjustNeeded = TRUE;
830 }
831 }
832 /* Do we need to adjust timestamps? */
833 if (pHdr->bKnowIfAdjustNeeded &&
834 pHdr->bAdjustTimestamps &&
835 !bKey) {
836 dTSOffset = pHdr->ulBlockCount * pHdr->dBlockDuration;
837 ulTSOffset = (UINT32)(dTSOffset + 0.5);
838 ulPacketTime += ulTSOffset;
839 }
840 /* Compute the index of the block within the superblock */
841 dTimeDiff = (HXDOUBLE)(ulPacketTime - pHdr->ulKeyTime);
842#ifndef __ARC600__
843 if (pHdr->dBlockDuration)
844#else
845 if (pHdr->dBlockDuration == 0.0) {
846 ;
847 } else
848#endif
849 {
850 dBlockNum = dTimeDiff / pHdr->dBlockDuration;
851 }
852 ulBlockNum = (UINT32)(dBlockNum + 0.5);
853 /* Is this block beyond our superblock? */
854 if (ulBlockNum >= pHdr->ulInterleaveFactor) {
855 /*
856 * We must have had loss at the end of the
857 * previous superblock, since we have received
858 * a packet in the next superblock without having
859 * sent the current superblock. Therefore, we attempt
860 * to finish out the current superblock and send it.
861 */
862 retVal = ra_depacki_deinterleave_send(pInt, ulSubStream);
863 if (retVal == HXR_OK) {
864 /* Now we need to update the block index */
865 if (bKey) {
866 /*
867 * This packet is a keyframe packet, so
868 * we simply assign the new time and set
869 * the block index to 0.
870 */
871 pHdr->ulKeyTime = pPacket->ulTime;
872 ulBlockNum = 0;
873 } else {
874 /*
875 * This is not a keyframe packet, so we need to
876 * keep adding the superblock time to the key time
877 * and keep subtracting interleave factor to the block
878 * index until we reach the range [0,intereaveFactor-1]
879 * for the index.
880 */
881 do {
882 pHdr->ulKeyTime += pHdr->ulSuperBlockTime;
883 ulBlockNum -= pHdr->ulInterleaveFactor;
884 } while (ulBlockNum < pHdr->ulInterleaveFactor);
885 }
886 }
887 }
888 /* Sanity check on buffer copy parameters */
889 if (ulBlockNum < pHdr->ulInterleaveFactor &&
890 ((UINT32) pPacket->usDataLen) == pHdr->ulInterleaveBlockSize &&
891 pHdr->pIPresentFlags) {
892 /* Copy the data into the interleave buffer */
893 memcpy(pHdr->pIBuffer + ulBlockNum * pHdr->ulInterleaveBlockSize,
894 pPacket->pData,
895 pHdr->ulInterleaveBlockSize);
896 /* Set all the flags to be present for this block */
897 pHdr->pIPresentFlags[ulBlockNum] = 0xFFFFFFFF;
898 /* Increment the block count in this superblock */
899 pHdr->ulBlockCount++;
900 /* Is this the last block in the superblock? */
901 if (ulBlockNum == pHdr->ulInterleaveFactor - 1) {
902 /* Deinterleave and send the blocks */
903 retVal = ra_depacki_deinterleave_send(pInt, ulSubStream);
904 } else {
905 /* Not ready to send yet. Clear the return */
906 retVal = HXR_OK;
907 }
908 }
909 } else {
910 /*
911 * We don't have a key block time or the key block time
912 * that we have is greater than the packet time, so we
913 * can't compute what slot this block should be in. This
914 * probably occurred because of loss at the beginning of the
915 * stream. We have to throw this packet away.
916 */
917 retVal = HXR_OK;
918 }
919 } else {
920 /*
921 * The packet was lost. For now, don't do anything
922 * with the packet. We will deduce loss based entirely
923 * on timestamps for now.
924 */
925 retVal = HXR_OK;
926 }
927 /* Save the information about the last packet */
928 pHdr->lastPacket.ulTime = pPacket->ulTime;
929 pHdr->lastPacket.usStream = pPacket->usStream;
930 pHdr->lastPacket.usASMFlags = pPacket->usASMFlags;
931 pHdr->lastPacket.ucASMRule = pPacket->ucASMRule;
932 pHdr->lastPacket.ucLost = pPacket->ucLost;
933 pHdr->bHasLastPacket = TRUE;
934 }
935
936 return retVal;
937}
938
939HX_RESULT ra_depacki_parse_vbr_packet(ra_depack_internal* pInt,
940 rm_packet* pPacket,
941 UINT32* pulNumAU,
942 HXBOOL* pbFragmented,
943 UINT32* pulAUSize,
944 UINT32* pulAUFragSize)
945{
946 HX_RESULT retVal = HXR_FAIL;
947
948 if (pInt && pPacket && pulNumAU && pbFragmented &&
949 pulAUSize && pulAUFragSize &&
950 pPacket->pData && pPacket->usDataLen) {
951 /* Init local variables */
952 BYTE* pBuf = pPacket->pData;
953 UINT32 ulSize = pPacket->usDataLen;
954 UINT32 ulPacketSize = ulSize;
955 UINT32 ulAUHeaderSizeBits = 0;
956 UINT32 ulAUHeaderSize = 0;
957 UINT32 ulNumAU = 0;
958 UINT32 ulAUSize = 0;
959 UINT32 ulAUSizeTotal = 0;
960 UINT32 i = 0;
961 UINT32 ulExpectedSize = 0;
962 /* Sanity check on size */
963 if (ulSize >= 2) {
964 /* Get the AU header size in bits */
965 ulAUHeaderSizeBits = rm_unpack16(&pBuf, &ulSize);
966 /* Convert to bytes (rounding up to next byte) */
967 ulAUHeaderSize = (ulAUHeaderSizeBits + 7) >> 3;
968 /*
969 * Sanity check to make sure that the AU header size is
970 * greater than 0 and a multiple of 2 bytes
971 */
972 if (ulAUHeaderSize && !(ulAUHeaderSize & 1)) {
973 /*
974 * Since we know that each AU header is 2 bytes, then
975 * we know that the number of AU's in this packet is
976 * ulAUHeaderSize / 2.
977 */
978 ulNumAU = ulAUHeaderSize >> 1;
979 /*
980 * The audio/mpeg-generic spec says that each packet
981 * can either have a complete AU, a fragment of a single
982 * AU, or multiple complete AUs. Therefore, if the
983 * number of AUs is greater than 1, then we know we
984 * have ulNumAU *complete* AUs. Therefore, for more
985 * than one AU, we know what the exact size of the
986 * packet should be, and that should match up with
987 * the data size of the packet.
988 */
989 retVal = HXR_OK;
990 for (i = 0; i < ulNumAU && retVal == HXR_OK; i++) {
991 if (ulSize >= 2) {
992 ulAUSize = rm_unpack16(&pBuf, &ulSize);
993 ulAUSizeTotal += ulAUSize;
994 } else {
995 retVal = HXR_FAIL;
996 }
997 }
998 if (retVal == HXR_OK) {
999 /* Compute the expected size of the packet */
1000 ulExpectedSize = 2 + /* AU header size (16 bits) */
1001 ulNumAU * 2 + /* AU sizes */
1002 ulAUSizeTotal; /* the AU's themselves */
1003 /*
1004 * Check this against the actual size. If we have
1005 * 1 AU, then the expected size can be greater than
1006 * the actual size due to fragmentation. If we have
1007 * more than more AU, then the expected size MUST
1008 * match the actual size.
1009 */
1010 if (ulNumAU > 1) {
1011 if (ulExpectedSize == ulPacketSize) {
1012 /* Multiple AUs, no fragmentation */
1013 *pbFragmented = FALSE;
1014 } else {
1015 /* Something wrong */
1016 retVal = HXR_FAIL;
1017 }
1018 } else if (ulNumAU == 1) {
1019 if (ulExpectedSize > ulPacketSize) {
1020 /* Fragmented single AU */
1021 *pbFragmented = TRUE;
1022 } else {
1023 /* Single AU, no fragmentation */
1024 *pbFragmented = FALSE;
1025 }
1026 /* Set the AU size */
1027 *pulAUSize = ulAUSizeTotal;
1028 *pulAUFragSize = ulPacketSize - 4;
1029 }
1030 /* Assign the number of AU out parameter */
1031 if (retVal == HXR_OK) {
1032 *pulNumAU = ulNumAU;
1033 }
1034 }
1035 }
1036 }
1037 }
1038
1039 return retVal;
1040}
1041
1042HX_RESULT ra_depacki_generate_and_send_loss(ra_depack_internal* pInt,
1043 UINT32 ulSubStream,
1044 UINT32 ulFirstStartTime,
1045 UINT32 ulLastEndTime)
1046{
1047 HX_RESULT retVal = HXR_FAIL;
1048
1049 if (pInt && ulSubStream < pInt->multiStreamHdr.ulNumSubStreams &&
1050 ulLastEndTime > ulFirstStartTime) {
1051 HXDOUBLE dAUDuration = pInt->pSubStreamHdr[ulSubStream].dBlockDuration;
1052 HXDOUBLE dDiff = ulLastEndTime - ulFirstStartTime;
1053 UINT32 ulNumLossPackets = 0;
1054 UINT32 i = 0;
1055 UINT32 ulTSOffset = 0;
1056 UINT32 ulTime = 0;
1057 /* Compute the number of packets */
1058#ifndef __ARC600__
1059 if (dAUDuration != 0.0)
1060#else
1061 if (dAUDuration == 0.0) {
1062 ;
1063 } else
1064#endif
1065 {
1066 ulNumLossPackets = (UINT32)(dDiff / dAUDuration);
1067 }
1068 /* Clear the return value */
1069 retVal = HXR_OK;
1070 /* Generate loss packets */
1071 for (i = 0; i < ulNumLossPackets && HX_SUCCEEDED(retVal); i++) {
1072 ulTSOffset = (UINT32)(i * dAUDuration);
1073 ulTime = ulFirstStartTime + ulTSOffset;
1074 retVal = ra_depacki_send_block(pInt,
1075 ulSubStream,
1076 HXNULL,
1077 0,
1078 ulTime,
1079 0); /* Flags of 0 indicate loss */
1080 }
1081 }
1082
1083 return retVal;
1084}
1085
1086#if RA_COPY_BUF
1087void ra_depacki_free_block(ra_block* pBlock)
1088{
1089 /* Free the data */
1090 if (pBlock->pData) {
1091 AVMem_free(pBlock->pData);
1092 pBlock->pData = HXNULL;
1093 }
1094}
1095#endif
1096
1097HX_RESULT ra_depacki_send_block(ra_depack_internal* pInt,
1098 UINT32 ulSubStream,
1099 BYTE* pBuf,
1100 UINT32 ulLen,
1101 UINT32 ulTime,
1102 UINT32 ulFlags)
1103{
1104 HX_RESULT retVal = HXR_FAIL;
1105
1106 if (pInt && pInt->fpAvail) {
1107 /* Allocate space for a ra_block structure */
1108 ra_block Block;
1109 memset(&Block, 0, sizeof(Block));
1110 {
1111 /* Clear the return value */
1112 retVal = HXR_OK;
1113 /* Copy the buffer */
1114 if (pBuf && ulLen) {
1115#if RA_COPY_BUF
1116 Block.pData = copy_buffer(pInt->pUserMem,
1117 pInt->fpMalloc,
1118 pBuf, ulLen);
1119 if (Block.pData) {
1120 Block.ulDataLen = ulLen;
1121 } else {
1122 retVal = HXR_OUTOFMEMORY;
1123 }
1124#else
1125 Block.pData = pBuf;
1126 Block.ulDataLen = ulLen;
1127#endif
1128 }
1129 if (retVal == HXR_OK) {
1130 /* Assign the timestamp and flags */
1131 Block.ulTimestamp = ulTime;
1132 Block.ulDataFlags = ulFlags;
1133 /* Send the block */
1134 retVal = pInt->fpAvail(pInt->pAvail,
1135 ulSubStream,
1136 &Block);
1137 }
1138#if RA_COPY_BUF
1139 ra_depacki_free_block(&Block);
1140#endif
1141 }
1142 }
1143
1144 return retVal;
1145}
1146
1147HX_RESULT ra_depacki_handle_frag_packet(ra_depack_internal* pInt,
1148 UINT32 ulSubStream,
1149 rm_packet* pPacket,
1150 UINT32 ulAUSize,
1151 UINT32 ulAUFragSize)
1152{
1153 HX_RESULT retVal = HXR_FAIL;
1154
1155 if (pInt && pInt->pSubStreamHdr && pPacket &&
1156 ulSubStream < pInt->multiStreamHdr.ulNumSubStreams) {
1157 UINT32 ulPacketSize = (UINT32) pPacket->usDataLen;
1158 UINT32 ulPacketOffset = (ulPacketSize >= ulAUFragSize ?
1159 ulPacketSize - ulAUFragSize : 0);
1160 /* Get the substream header */
1161 ra_substream_hdr* pHdr = &pInt->pSubStreamHdr[ulSubStream];
1162 /* Clear the return value */
1163 retVal = HXR_OK;
1164 /* Have we allocated the frag buffer yet? */
1165 if (!pHdr->pFragBuffer) {
1166 retVal = ra_depacki_init_frag_buffer(pInt, pHdr);
1167 }
1168 if (HX_SUCCEEDED(retVal)) {
1169 /*
1170 * Do we have a current fragment, and if so, is it
1171 * a different timestamp from this fragment?
1172 */
1173 if (pHdr->bHasFrag && pHdr->ulFragBufferTime != pPacket->ulTime) {
1174 /* Clear the frag buffer */
1175 ra_depacki_clear_frag_buffer(pInt, pHdr);
1176 }
1177 /*
1178 * Are we currently processing a fragment? If not,
1179 * then initialize this fragment, resizing the
1180 * buffer if necessary.
1181 */
1182 if (!pHdr->bHasFrag) {
1183 /* Make sure the buffer size is big enough */
1184 if (ulAUSize > pHdr->ulFragBufferSize) {
1185 retVal = ra_depacki_resize_frag_buffer(pInt, pHdr, ulAUSize);
1186 }
1187 if (HX_SUCCEEDED(retVal)) {
1188 /* Init the members for this fragment */
1189 pHdr->ulFragBufferOffset = 0;
1190 pHdr->ulFragBufferTime = pPacket->ulTime;
1191 pHdr->ulFragBufferAUSize = ulAUSize;
1192 pHdr->bHasFrag = TRUE;
1193 }
1194 }
1195 if (HX_SUCCEEDED(retVal)) {
1196 /* Make sure we have room for the memcpy */
1197 if (pHdr->ulFragBufferOffset + ulAUFragSize <= pHdr->ulFragBufferSize &&
1198 ulPacketOffset + ulAUFragSize <= ulPacketSize) {
1199 /* Copy this buffer in */
1200 memcpy(pHdr->pFragBuffer + pHdr->ulFragBufferOffset,
1201 pPacket->pData + ulPacketOffset,
1202 ulAUFragSize);
1203 /* Update the frag buffer offset */
1204 pHdr->ulFragBufferOffset += ulAUFragSize;
1205 /* Have we finished the fragmented AU? */
1206 if (pHdr->ulFragBufferOffset >= pHdr->ulFragBufferAUSize) {
1207 /* Send the frag buffer */
1208 retVal = ra_depacki_send_block(pInt, ulSubStream,
1209 pHdr->pFragBuffer,
1210 pHdr->ulFragBufferAUSize,
1211 pHdr->ulFragBufferTime,
1212 0xFFFFFFFF);
1213 /* Whether we succeed or not, clear the frag buffer */
1214 ra_depacki_clear_frag_buffer(pInt, pHdr);
1215 }
1216 } else {
1217 retVal = HXR_FAIL;
1218 }
1219 }
1220 }
1221 }
1222
1223 return retVal;
1224}
1225
1226HX_RESULT ra_depacki_handle_nonfrag_packet(ra_depack_internal* pInt,
1227 UINT32 ulSubStream,
1228 rm_packet* pPacket,
1229 UINT32 ulNumAU)
1230{
1231 HX_RESULT retVal = HXR_FAIL;
1232
1233 if (pInt && pInt->pSubStreamHdr && pPacket &&
1234 ulSubStream < pInt->multiStreamHdr.ulNumSubStreams) {
1235 /* Init the local variables */
1236 UINT32 ulAUDataSizeSum = 0;
1237 UINT32 i = 0;
1238 BYTE* pBuf = pPacket->pData;
1239 UINT32 ulLen = pPacket->usDataLen;
1240 UINT32 ulTSOffset = 0;
1241 UINT32 ulAUSize = 0;
1242 UINT32 ulBufOffset = 0;
1243 /* Get the substream header */
1244 ra_substream_hdr* pHdr = &pInt->pSubStreamHdr[ulSubStream];
1245 /*
1246 * We can clear the frag queue. If there was no
1247 * loss in the last fragmented AU, then it was
1248 * cleared after the packet was created. If there
1249 * WAS loss in the last fragmented AU, then we
1250 * just handled it by generating loss packets.
1251 */
1252 ra_depacki_clear_frag_buffer(pInt, pHdr);
1253 /* Clear the return value */
1254 retVal = HXR_OK;
1255 /* Step through the packet sending blocks */
1256 for (i = 0; i < ulNumAU && HX_SUCCEEDED(retVal); i++) {
1257 /* Set the return value */
1258 retVal = HXR_FAIL;
1259 /* Compute the time offset for this block */
1260 ulTSOffset = (UINT32)(i * pHdr->dBlockDuration);
1261 /* Compute the buffer offset for the AU size */
1262 ulBufOffset = 2 + (i << 1);
1263 /* Sanity check on packet size */
1264 if (ulBufOffset + 1 < ulLen) {
1265 /* Parse out the size of this AU */
1266 ulAUSize = rm_unpack16_nse(pBuf + ulBufOffset,
1267 ulLen - ulBufOffset);
1268 /* Compute the offset of the AU */
1269 ulBufOffset = 2 + ulNumAU * 2 + ulAUDataSizeSum;
1270 /* Sanity check on size */
1271 if (ulBufOffset + ulAUSize <= ulLen) {
1272 /* Send this AU */
1273 retVal = ra_depacki_send_block(pInt,
1274 ulSubStream,
1275 pBuf + ulBufOffset,
1276 ulAUSize,
1277 pPacket->ulTime + ulTSOffset,
1278 0xFFFFFFFF);
1279 if (retVal == HXR_OK) {
1280 /* Update the AU data size sum */
1281 ulAUDataSizeSum += ulAUSize;
1282 }
1283 }
1284 }
1285 }
1286 if (HX_SUCCEEDED(retVal)) {
1287 /* Update the end time of the last block sent */
1288 ulTSOffset = (UINT32)(ulNumAU * pHdr->dBlockDuration);
1289 pHdr->ulLastSentEndTime = pPacket->ulTime + ulTSOffset;
1290 }
1291 }
1292
1293 return retVal;
1294}
1295
1296HX_RESULT ra_depacki_init_frag_buffer(ra_depack_internal* pInt,
1297 ra_substream_hdr* pHdr)
1298{
1299 HX_RESULT retVal = HXR_FAIL;
1300
1301 if (pInt && pHdr && !pHdr->pFragBuffer) {
1302 /* Allocate the frag buffer */
1303 pHdr->pFragBuffer = ra_depacki_malloc(pInt, INITIAL_FRAG_BUFFER_SIZE);
1304 if (pHdr->pFragBuffer) {
1305 /* Zero out the buffer */
1306 memset(pHdr->pFragBuffer, 0, INITIAL_FRAG_BUFFER_SIZE);
1307 /* Init the members */
1308 pHdr->ulFragBufferSize = INITIAL_FRAG_BUFFER_SIZE;
1309 pHdr->ulFragBufferTime = 0;
1310 pHdr->ulFragBufferOffset = 0;
1311 pHdr->ulFragBufferAUSize = 0;
1312 pHdr->bHasFrag = FALSE;
1313 }
1314 }
1315
1316 return retVal;
1317}
1318
1319HX_RESULT ra_depacki_resize_frag_buffer(ra_depack_internal* pInt,
1320 ra_substream_hdr* pHdr,
1321 UINT32 ulNewSize)
1322{
1323 HX_RESULT retVal = HXR_FAIL;
1324
1325 if (pInt && pHdr && pHdr->pFragBuffer) {
1326 /* Allocate a new buffer */
1327 BYTE* pNewBuf = ra_depacki_malloc(pInt, ulNewSize);
1328 if (pNewBuf) {
1329 /* Copy the old buffer */
1330 if (pHdr->ulFragBufferOffset) {
1331 memcpy(pNewBuf, pHdr->pFragBuffer, pHdr->ulFragBufferOffset);
1332 }
1333 /* NULL out the rest of the buffer */
1334 memset(pNewBuf + pHdr->ulFragBufferOffset, 0,
1335 ulNewSize - pHdr->ulFragBufferOffset);
1336 /* Free the old buffer */
1337 ra_depacki_free(pInt, pHdr->pFragBuffer);
1338 /* Assign the members. We won't change time or offset */
1339 pHdr->pFragBuffer = pNewBuf;
1340 pHdr->ulFragBufferSize = ulNewSize;
1341 /* Clear the return value */
1342 retVal = HXR_OK;
1343 }
1344 }
1345
1346 return retVal;
1347}
1348
1349void ra_depacki_clear_frag_buffer(ra_depack_internal* pInt,
1350 ra_substream_hdr* hdr)
1351{
1352 if (pInt && hdr && hdr->bHasFrag) {
1353 /* Clear the frag buffer members */
1354 hdr->bHasFrag = FALSE;
1355 hdr->ulFragBufferAUSize = 0;
1356 hdr->ulFragBufferOffset = 0;
1357 hdr->ulFragBufferTime = 0;
1358 }
1359}
1360
1361HX_RESULT ra_depacki_seek(ra_depack_internal* pInt, UINT32 ulTime)
1362{
1363 HX_RESULT retVal = HXR_FAIL;
1364
1365 if (pInt && pInt->pSubStreamHdr) {
1366 /*
1367 * Loop through all the substream headers
1368 * and set the bSeeked flag.
1369 */
1370 UINT32 i = 0;
1371 for (i = 0; i < pInt->multiStreamHdr.ulNumSubStreams; i++) {
1372 pInt->pSubStreamHdr[i].bSeeked = TRUE;
1373 }
1374 }
1375
1376 return retVal;
1377}
1378
1379HX_RESULT ra_depacki_deinterleave_send(ra_depack_internal* pInt, UINT32 ulSubStream)
1380{
1381 HX_RESULT retVal = HXR_FAIL;
1382
1383 if (pInt && pInt->pSubStreamHdr &&
1384 ulSubStream < pInt->multiStreamHdr.ulNumSubStreams &&
1385 pInt->fpAvail) {
1386 /* Init local variables */
1387 UINT32 i = 0;
1388 UINT32 ulTimeOffset = 0;
1389 UINT32 ulTimestamp = 0;
1390 HXDOUBLE dTimeOffset = 0.0;
1391 ra_block Block;
1392 /* Deinterleave the superblock */
1393 retVal = ra_depacki_deinterleave(pInt, ulSubStream);
1394 if (retVal == HXR_OK) {
1395 /* Get the substream header */
1396 ra_substream_hdr* pHdr = &pInt->pSubStreamHdr[ulSubStream];
1397 /* Send the blocks from the deinterleave buffer */
1398 for (i = 0; i < pHdr->ulBlockCount && HX_SUCCEEDED(retVal); i++) {
1399 /* Set the return value */
1400 retVal = HXR_OUTOFMEMORY;
1401 /* Compute the time offset for this block */
1402 dTimeOffset = i * pHdr->dBlockDuration;
1403 ulTimeOffset = (UINT32) dTimeOffset;
1404 ulTimestamp = pHdr->ulKeyTime + ulTimeOffset;
1405 /* Make sure the time is less than the stream duration */
1406 if (ulTimestamp <= pInt->ulStreamDuration) {
1407#if RA_COPY_BUF
1408 /* Alloc and copy the buffer */
1409 Block.pData = copy_buffer(pInt->pUserMem,
1410 pInt->fpMalloc,
1411 pHdr->pDBuffer + i * pHdr->ulInterleaveBlockSize,
1412 pHdr->ulInterleaveBlockSize);
1413#else
1414 Block.pData = pHdr->pDBuffer + i * pHdr->ulInterleaveBlockSize;
1415#endif
1416 if (Block.pData) {
1417 Block.ulDataLen = pHdr->ulInterleaveBlockSize;
1418 Block.ulTimestamp = ulTimestamp;
1419 Block.ulDataFlags = pHdr->pDPresentFlags[i];
1420 /* Send the block */
1421 retVal = pInt->fpAvail(pInt->pAvail, ulSubStream, &Block);
1422 }
1423#if RA_COPY_BUF
1424 ra_depacki_free_block(&Block);
1425#endif
1426 } else {
1427 /*
1428 * Block is after the stream duration, so clear
1429 * the return value and break out of the loop.
1430 */
1431 retVal = HXR_OK;
1432 break;
1433 }
1434 }
1435 /* Clear the interleaving buffers */
1436 memset(pHdr->pIBuffer, 0, pHdr->ulSuperBlockSize);
1437 memset(pHdr->pDBuffer, 0, pHdr->ulSuperBlockSize);
1438 memset(pHdr->pIPresentFlags, 0, pHdr->ulInterleaveFactor * sizeof(UINT32));
1439 memset(pHdr->pDPresentFlags, 0, pHdr->ulInterleaveFactor * sizeof(UINT32));
1440 /* Clear the state */
1441 pHdr->bHasKeyTime = FALSE;
1442 pHdr->ulKeyTime = 0;
1443 pHdr->ulBlockCount = 0;
1444 }
1445 }
1446
1447 return retVal;
1448}
1449
1450HX_RESULT ra_depacki_deinterleave(ra_depack_internal* pInt, UINT32 ulSubStream)
1451{
1452 HX_RESULT retVal = HXR_FAIL;
1453
1454 if (pInt && pInt->pSubStreamHdr &&
1455 ulSubStream < pInt->multiStreamHdr.ulNumSubStreams) {
1456 /* Get the interleaver ID */
1457 UINT32 ulID = pInt->pSubStreamHdr[ulSubStream].ulInterleaverID;
1458 /* Switch based on ID */
1459 switch (ulID) {
1460#if 0
1461 case RA_INTERLEAVER_SIPR:
1462 retVal = ra_depacki_deinterleave_sipr(pInt, ulSubStream);
1463 break;
1464#endif
1465 case RA_INTERLEAVER_GENR:
1466 retVal = ra_depacki_deinterleave_genr(pInt, ulSubStream);
1467 break;
1468 case RA_NO_INTERLEAVER:
1469 retVal = ra_depacki_deinterleave_no(pInt, ulSubStream);
1470 break;
1471 }
1472 }
1473
1474 return retVal;
1475}
1476
1477#if 0
1478HX_RESULT ra_depacki_deinterleave_sipr(ra_depack_internal* pInt, UINT32 ulSubStream)
1479{
1480 HX_RESULT retVal = HXR_FAIL;
1481
1482 if (pInt && pInt->pSubStreamHdr &&
1483 ulSubStream < pInt->multiStreamHdr.ulNumSubStreams) {
1484 /* Get the substream header */
1485 ra_substream_hdr* pHdr = &pInt->pSubStreamHdr[ulSubStream];
1486 /* Sanity check */
1487 if (pHdr->pIBuffer && pHdr->pDBuffer &&
1488 pHdr->pIPresentFlags && pHdr->pDPresentFlags) {
1489 /*
1490 * This is an in-place interleaving, so copy from
1491 * pIBuffer to pDBuffer and then we will do the
1492 * de-interleaving in-place in pDBuffer.
1493 */
1494 memcpy(pHdr->pDBuffer, pHdr->pIBuffer, pHdr->ulSuperBlockSize);
1495 /* Copy the flags */
1496 memcpy(pHdr->pDPresentFlags, pHdr->pIPresentFlags,
1497 pHdr->ulInterleaveFactor * sizeof(UINT32));
1498 /* Do the de-interleave */
1499 RASL_DeInterleave((char*) pHdr->pDBuffer,
1500 pHdr->ulSuperBlockSize,
1501 pHdr->usFlavorIndex,
1502 pHdr->pDPresentFlags);
1503 /* Clear the return value */
1504 retVal = HXR_OK;
1505 }
1506 }
1507
1508 return retVal;
1509}
1510#endif
1511
1512HX_RESULT ra_depacki_init_genr(ra_depack_internal* pInt, UINT32 ulSubStream)
1513{
1514 HX_RESULT retVal = HXR_FAIL;
1515
1516 if (pInt && pInt->pSubStreamHdr &&
1517 ulSubStream < pInt->multiStreamHdr.ulNumSubStreams) {
1518 /* Init local variables */
1519 UINT32 ulFramesPerBlock = 0;
1520 UINT32 ulSize = 0;
1521 UINT32 ulBlockIndx = 0;
1522 UINT32 ulFrameIndx = 0;
1523 UINT32 ulIndx = 0;
1524 UINT32 i = 0;
1525 UINT32 j = 0;
1526 UINT32 ulCount = 0;
1527 HXBOOL bEven = FALSE;
1528 /* Get the substream header */
1529 ra_substream_hdr* pHdr = &pInt->pSubStreamHdr[ulSubStream];
1530 /* Sanity check */
1531 if (pHdr->ulCodecFrameSize && pHdr->ulNumCodecFrames) {
1532 /* Compute the codec frames per block */
1533 ulFramesPerBlock = pHdr->ulInterleaveBlockSize / pHdr->ulCodecFrameSize;
1534 /* Allocate space for the block num and offset */
1535 ulSize = pHdr->ulNumCodecFrames * sizeof(UINT32);
1536 pHdr->pulGENRBlockNum = (UINT32*) ra_depacki_malloc(pInt, ulSize);
1537 if (pHdr->pulGENRBlockNum) {
1538 pHdr->pulGENRBlockOffset = (UINT32*) ra_depacki_malloc(pInt, ulSize);
1539 if (pHdr->pulGENRBlockOffset) {
1540 pHdr->pulGENRPattern = (UINT32*) ra_depacki_malloc(pInt, ulSize);
1541 if (pHdr->pulGENRPattern) {
1542 /* Initialize the block num and offset arrays */
1543 for (ulBlockIndx = 0; ulBlockIndx < pHdr->ulInterleaveFactor; ulBlockIndx++) {
1544 for (ulFrameIndx = 0; ulFrameIndx < ulFramesPerBlock; ulFrameIndx++) {
1545 ulIndx = ulBlockIndx * ulFramesPerBlock + ulFrameIndx;
1546 pHdr->pulGENRBlockNum[ulIndx] = ulBlockIndx;
1547 pHdr->pulGENRBlockOffset[ulIndx] = ulFrameIndx;
1548 }
1549 }
1550 /* Do we have a pattern from the stream header? */
1551 if (pHdr->pulInterleavePattern) {
1552 /* Copy the pattern from the stream header */
1553 memcpy(pHdr->pulGENRPattern,
1554 pHdr->pulInterleavePattern,
1555 ulSize);
1556 /*
1557 * Check the pattern for validity by making sure
1558 * that each frame index is used once and only
1559 * once in the interleave pattern.
1560 */
1561 retVal = HXR_OK;
1562 for (i = 0; i < pHdr->ulNumCodecFrames; i++) {
1563 /* Init the count */
1564 ulCount = 0;
1565 /* Count how many times index i appears in table */
1566 for (j = 0; j < pHdr->ulNumCodecFrames; j++) {
1567 if (pHdr->pulGENRPattern[j] == i) {
1568 ulCount++;
1569 }
1570 }
1571 /* Make sure it's just once */
1572 if (ulCount != 1) {
1573 retVal = HXR_FAIL;
1574 break;
1575 }
1576 }
1577 } else {
1578 /* Clear the return value */
1579 retVal = HXR_OK;
1580 /*
1581 * We don't have a stream header pattern, so
1582 * we generate the standard interleave pattern.
1583 */
1584 if (pHdr->ulInterleaveFactor == 1) {
1585 for (i = 0; i < pHdr->ulNumCodecFrames; i++) {
1586 pHdr->pulGENRPattern[i] = i;
1587 }
1588 } else {
1589 bEven = TRUE;
1590 ulCount = 0;
1591 ulBlockIndx = 0;
1592 ulFrameIndx = 0;
1593 while (ulCount < pHdr->ulNumCodecFrames) {
1594 pHdr->pulGENRPattern[ulCount] = ulBlockIndx * ulFramesPerBlock + ulFrameIndx;
1595 ulCount++;
1596 ulBlockIndx += 2;
1597 if (ulBlockIndx >= pHdr->ulInterleaveFactor) {
1598 if (bEven) {
1599 bEven = FALSE;
1600 ulBlockIndx = 1;
1601 } else {
1602 bEven = TRUE;
1603 ulBlockIndx = 0;
1604 ulFrameIndx++;
1605 }
1606 }
1607 }
1608 }
1609 }
1610 }
1611 }
1612 }
1613 }
1614 }
1615
1616 return retVal;
1617}
1618
1619HX_RESULT ra_depacki_deinterleave_genr(ra_depack_internal* pInt, UINT32 ulSubStream)
1620{
1621 HX_RESULT retVal = HXR_FAIL;
1622
1623 if (pInt && pInt->pSubStreamHdr &&
1624 ulSubStream < pInt->multiStreamHdr.ulNumSubStreams) {
1625 /* Init local variables */
1626 UINT32 fi = 0;
1627 UINT32 fo = 0;
1628 UINT32 ulBlkIndxIn = 0;
1629 UINT32 ulBlkIndxOut = 0;
1630 UINT32 ulBlkOffset = 0;
1631 /* Get the substream header */
1632 ra_substream_hdr* pHdr = &pInt->pSubStreamHdr[ulSubStream];
1633 /* Sanity check */
1634 if (pHdr->pIBuffer && pHdr->pDBuffer &&
1635 pHdr->pIPresentFlags && pHdr->pDPresentFlags) {
1636 /* Set all the output flags to present initially */
1637 memset(pHdr->pDPresentFlags, 0xFF,
1638 pHdr->ulInterleaveFactor * sizeof(UINT32));
1639 /* Deinterleave the data */
1640 for (fo = 0; fo < pHdr->ulNumCodecFrames; fo++) {
1641 /* Copy the data */
1642 fi = pHdr->pulGENRPattern[fo];
1643 memcpy(pHdr->pDBuffer + fo * pHdr->ulCodecFrameSize,
1644 pHdr->pIBuffer + fi * pHdr->ulCodecFrameSize,
1645 pHdr->ulCodecFrameSize);
1646 /* Look up which block this frame comes from */
1647 ulBlkIndxIn = pHdr->pulGENRBlockNum[fi];
1648 /* Is this codec frame present? */
1649 if (!pHdr->pIPresentFlags[ulBlkIndxIn]) {
1650 /*
1651 * Frame was part of a lost block. So clear
1652 * the bit that says the frame was present.
1653 */
1654 ulBlkIndxOut = pHdr->pulGENRBlockNum[fo];
1655 ulBlkOffset = pHdr->pulGENRBlockOffset[fo];
1656 pHdr->pDPresentFlags[ulBlkIndxOut] ^= (1 << ulBlkOffset);
1657 }
1658 }
1659 /* Clear the return value */
1660 retVal = HXR_OK;
1661 }
1662 }
1663
1664 return retVal;
1665}
1666
1667HX_RESULT ra_depacki_deinterleave_no(ra_depack_internal* pInt, UINT32 ulSubStream)
1668{
1669 HX_RESULT retVal = HXR_FAIL;
1670
1671 if (pInt && pInt->pSubStreamHdr &&
1672 ulSubStream < pInt->multiStreamHdr.ulNumSubStreams) {
1673 /* Init local variables */
1674 UINT32 fi = 0;
1675 UINT32 fo = 0;
1676 UINT32 ulBlkIndxIn = 0;
1677 UINT32 ulBlkIndxOut = 0;
1678 UINT32 ulBlkOffset = 0;
1679 /* Get the substream header */
1680 ra_substream_hdr* pHdr = &pInt->pSubStreamHdr[ulSubStream];
1681 /* Sanity check */
1682 if (pHdr->pIBuffer && pHdr->pDBuffer &&
1683 pHdr->pIPresentFlags && pHdr->pDPresentFlags) {
1684 /* Set all the output flags to present initially */
1685 memset(pHdr->pDPresentFlags, 0xFF,
1686 pHdr->ulInterleaveFactor * sizeof(UINT32));
1687 /* Deinterleave the data */
1688 for (fo = 0; fo < pHdr->ulNumCodecFrames; fo++) {
1689 /* Copy the data */
1690 fi = fo;
1691 memcpy(pHdr->pDBuffer + fo * pHdr->ulCodecFrameSize,
1692 pHdr->pIBuffer + fi * pHdr->ulCodecFrameSize,
1693 pHdr->ulCodecFrameSize);
1694 /* Look up which block this frame comes from */
1695 ulBlkIndxIn = pHdr->pulGENRBlockNum[fi];
1696 /* Is this codec frame present? */
1697 if (!pHdr->pIPresentFlags[ulBlkIndxIn]) {
1698 /*
1699 * Frame was part of a lost block. So clear
1700 * the bit that says the frame was present.
1701 */
1702 ulBlkIndxOut = pHdr->pulGENRBlockNum[fo];
1703 ulBlkOffset = pHdr->pulGENRBlockOffset[fo];
1704 pHdr->pDPresentFlags[ulBlkIndxOut] ^= (1 << ulBlkOffset);
1705 }
1706 }
1707 /* Clear the return value */
1708 retVal = HXR_OK;
1709 }
1710 }
1711
1712 return retVal;
1713}
1714