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 | |
21 | void* 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 | |
32 | void ra_depacki_free(ra_depack_internal* pInt, void* pMem) |
33 | { |
34 | if (pInt && pInt->fpFree) { |
35 | pInt->fpFree(pInt->pUserMem, pMem); |
36 | } |
37 | } |
38 | |
39 | HX_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 | |
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 | /* 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 | |
453 | HX_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 | |
564 | HX_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 | |
602 | void 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 | |
611 | UINT32 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 | |
623 | HXBOOL 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 | |
629 | UINT32 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 | |
641 | HX_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 | |
699 | HX_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 | |
767 | HX_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 | |
936 | HX_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 | |
1039 | HX_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 |
1084 | void 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 | |
1094 | HX_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 | |
1144 | HX_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 | |
1223 | HX_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 | |
1293 | HX_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 | |
1316 | HX_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 | |
1346 | void 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 | |
1358 | HX_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 | |
1376 | HX_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 | |
1447 | HX_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 |
1475 | HX_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 | |
1509 | HX_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 | |
1616 | HX_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 | |
1664 | HX_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 |