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