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 | |
20 | void* 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 | |
31 | void ra_depacki_free(ra_depack_internal* pInt, void* pMem) |
32 | { |
33 | if (pInt && pInt->fpFree) { |
34 | pInt->fpFree(pInt->pUserMem, pMem); |
35 | } |
36 | } |
37 | |
38 | HX_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 | |
93 | HX_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 | |
111 | HX_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 | |
128 | HX_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 | |
294 | void 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 | |
341 | void 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 | |
355 | HX_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 | |
390 | HX_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 | |
398 | HX_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 | |
456 | HX_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 | |
567 | HX_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 | |
605 | void 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 | |
614 | UINT32 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 | |
626 | HXBOOL 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 | |
632 | UINT32 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 | |
644 | HX_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 | |
702 | HX_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 | |
771 | HX_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 | |
939 | HX_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 | |
1042 | HX_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 |
1087 | void 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 | |
1097 | HX_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 | |
1147 | HX_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 | |
1226 | HX_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 | |
1296 | HX_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 | |
1319 | HX_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 | |
1349 | void 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 | |
1361 | HX_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 | |
1379 | HX_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 | |
1450 | HX_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 |
1478 | HX_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 | |
1512 | HX_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 | |
1619 | HX_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 | |
1667 | HX_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 |