summaryrefslogtreecommitdiff
path: root/audio_codec/libcook/ra8lbr_decode.c (plain)
blob: 729d99c5ab7a25d4d3021de16ef01352a6d4ba82
1/* ***** BEGIN LICENSE BLOCK *****
2 * Source last modified: $Id: ra8lbr_decode.c,v 1.2.2.1 2005/05/04 18:21:53 hubbe Exp $
3 *
4 * REALNETWORKS CONFIDENTIAL--NOT FOR DISTRIBUTION IN SOURCE CODE FORM
5 * Portions Copyright (c) 1995-2005 RealNetworks, Inc.
6 * All Rights Reserved.
7 *
8 * The contents of this file, and the files included with this file,
9 * are subject to the current version of the Real Format Source Code
10 * Porting and Optimization License, available at
11 * https://helixcommunity.org/2005/license/realformatsource (unless
12 * RealNetworks otherwise expressly agrees in writing that you are
13 * subject to a different license). You may also obtain the license
14 * terms directly from RealNetworks. You may not use this file except
15 * in compliance with the Real Format Source Code Porting and
16 * Optimization License. There are no redistribution rights for the
17 * source code of this file. Please see the Real Format Source Code
18 * Porting and Optimization License for the rights, obligations and
19 * limitations governing use of the contents of the file.
20 *
21 * RealNetworks is the developer of the Original Code and owns the
22 * copyrights in the portions it created.
23 *
24 * This file, and the files included with this file, is distributed and
25 * made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND,
26 * EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL
27 * SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT
29 * OR NON-INFRINGEMENT.
30 *
31 * Technology Compatibility Kit Test Suite(s) Location:
32 * https://rarvcode-tck.helixcommunity.org
33 *
34 * Contributor(s):
35 *
36 * ***** END LICENSE BLOCK ***** */
37
38//#include <string.h>
39//#include <core/dsp.h>
40#include "helix_types.h"
41#include "helix_result.h"
42#include "ra8lbr_decode.h"
43#include "ra_format_info.h"
44#include "gecko2codec.h"
45#include <stdio.h>
46
47#define GECKO_VERSION ((1L<<24)|(0L<<16)|(0L<<8)|(3L))
48#define GECKO_MC1_VERSION ((2L<<24)|(0L<<16)|(0L<<8)|(0L))
49
50HX_RESULT ra8lbr_unpack_opaque_data(ra8lbr_data* pData,
51 UINT8* pBuf,
52 UINT32 ulLength);
53
54/*
55 * ra8lbr_decode_init
56 */
57HX_RESULT
58ra8lbr_decode_init(void* pInitParams,
59 UINT32 ulInitParamsSize,
60 ra_format_info* pStreamInfo,
61 void** pDecode,
62 void* pUserMem,
63 rm_malloc_func_ptr fpMalloc,
64 rm_free_func_ptr fpFree)
65{
66 HX_RESULT retVal = HXR_FAIL;
67 ra8lbr_decode* pDec;
68 ra8lbr_data unpackedData;
69 UINT32 nChannels, frameSizeInBits;
70
71 pDec = (ra8lbr_decode*) fpMalloc(pUserMem, sizeof(ra8lbr_decode));
72
73 if (pDec) {
74 memset(pDec, 0, sizeof(ra8lbr_decode));
75 *pDecode = (void *)pDec;
76 retVal = ra8lbr_unpack_opaque_data(&unpackedData,
77 pStreamInfo->pOpaqueData,
78 pStreamInfo->ulOpaqueDataSize);
79
80 if (retVal == HXR_OK) {
81 /* save the stream info and init data we'll need later */
82 pDec->ulNumChannels = (UINT32)pStreamInfo->usNumChannels;
83 pDec->ulFrameSize = pStreamInfo->ulBitsPerFrame;
84 pDec->ulFramesPerBlock = pStreamInfo->ulGranularity / pDec->ulFrameSize;
85 pDec->ulSamplesPerFrame = unpackedData.nSamples;
86 pDec->ulSampleRate = pStreamInfo->ulSampleRate;
87
88 /* multichannel not supported, use simple logic for channel mask */
89 if (pDec->ulNumChannels == 1) {
90 pDec->ulChannelMask = 0x00004;
91 } else if (pDec->ulNumChannels == 2) {
92 pDec->ulChannelMask = 0x00003;
93 } else {
94 pDec->ulChannelMask = 0x00003;
95 }
96 if (pDec->ulNumChannels > 2) {
97 pDec->ulNumChannels = 2;
98 }
99 nChannels = pDec->ulNumChannels;
100 frameSizeInBits = pDec->ulFrameSize * 8;
101
102 /* initialize the decoder backend and save a reference to it */
103
104 pDec->pDecoder = Gecko2InitDecoder(pDec->ulSamplesPerFrame / nChannels,
105 nChannels,
106 unpackedData.nRegions,
107 frameSizeInBits,
108 pDec->ulSampleRate,
109 unpackedData.cplStart,
110 unpackedData.cplQBits,
111 (INT32 *)&pDec->ulDelayFrames);
112
113 /* Allocate a dummy input frame for flushing the decoder */
114 pDec->pFlushData = (UCHAR *) fpMalloc(pUserMem, pDec->ulFrameSize);
115
116 if (pDec->pDecoder == HXNULL || pDec->pFlushData == HXNULL) {
117 retVal = HXR_FAIL;
118 } else {
119 /* fill the dummy input frame with zeros */
120 memset(pDec->pFlushData, 0, pDec->ulFrameSize);
121
122 /* Set number of delay samples to discard on decoder start */
123 pDec->ulDelayRemaining = pDec->ulDelayFrames * pDec->ulSamplesPerFrame;
124 }
125 }
126 }
127
128 return retVal;
129}
130
131HX_RESULT
132ra8lbr_decode_reset(void* pDecode,
133 UINT16* pSamplesOut,
134 UINT32 ulNumSamplesAvail,
135 UINT32* pNumSamplesOut)
136{
137 HX_RESULT retVal = HXR_FAIL;
138 ra8lbr_decode* pDec = (ra8lbr_decode*) pDecode;
139 UINT32 n, framesToDecode;
140
141 *pNumSamplesOut = 0;
142
143 if (pSamplesOut != HXNULL) {
144 framesToDecode = pDec->ulDelayFrames;
145 if (framesToDecode * pDec->ulSamplesPerFrame > ulNumSamplesAvail) {
146 framesToDecode = ulNumSamplesAvail / pDec->ulSamplesPerFrame;
147 }
148
149 for (n = 0; n < framesToDecode; n++) {
150 retVal = Gecko2Decode(pDec->pDecoder, pDec->pFlushData,
151 0xFFFFFFFFUL, (INT16 *)pSamplesOut + *pNumSamplesOut, 0);
152 *pNumSamplesOut += pDec->ulSamplesPerFrame;
153 }
154
155 /* reset the delay compensation */
156 pDec->ulDelayRemaining = pDec->ulDelayFrames * pDec->ulSamplesPerFrame;
157 }
158
159 return retVal;
160}
161
162HX_RESULT
163ra8lbr_decode_conceal(void* pDecode,
164 UINT32 ulNumSamples)
165{
166 ra8lbr_decode* pDec = (ra8lbr_decode*) pDecode;
167 pDec->ulFramesToConceal = ulNumSamples / pDec->ulSamplesPerFrame;
168
169 return HXR_OK;
170}
171
172HX_RESULT
173ra8lbr_decode_decode(void* pDecode,
174 UINT8* pData,
175 UINT32 ulNumBytes,
176 UINT32* pNumBytesConsumed,
177 UINT16* pSamplesOut,
178 UINT32 ulNumSamplesAvail,
179 UINT32* pNumSamplesOut,
180 UINT32 ulFlags,
181 UINT32 ulTimeStamp)
182{
183 HX_RESULT retVal = HXR_FAIL;
184 ra8lbr_decode* pDec = (ra8lbr_decode*) pDecode;
185 UINT32 n, framesToDecode, lostFlag;
186 UINT8* inBuf = pData;
187 UINT16* outBuf = pSamplesOut;
188
189 *pNumBytesConsumed = 0;
190 *pNumSamplesOut = 0;
191 framesToDecode = 0;
192
193 if (pDec->ulFramesToConceal != 0) {
194 if (pDec->ulFramesToConceal > ulNumSamplesAvail / pDec->ulSamplesPerFrame) {
195 framesToDecode = ulNumSamplesAvail / pDec->ulSamplesPerFrame;
196 pDec->ulFramesToConceal -= framesToDecode;
197 } else {
198 framesToDecode = pDec->ulFramesToConceal;
199 pDec->ulFramesToConceal = 0;
200 }
201
202 inBuf = pDec->pFlushData;
203
204 for (n = 0; n < framesToDecode; n++) {
205 retVal = Gecko2Decode(pDec->pDecoder, inBuf, 0xFFFFFFFFUL, (INT16 *)outBuf, ulTimeStamp);
206
207 if (retVal != 0) {
208 retVal = HXR_FAIL;
209 break;
210 }
211
212 outBuf += pDec->ulSamplesPerFrame;
213 *pNumSamplesOut += pDec->ulSamplesPerFrame;
214 }
215 } else if (ulNumBytes % pDec->ulFrameSize == 0) {
216 framesToDecode = ulNumBytes / pDec->ulFrameSize;
217
218 if (framesToDecode > ulNumSamplesAvail / pDec->ulSamplesPerFrame) {
219 framesToDecode = ulNumSamplesAvail / pDec->ulSamplesPerFrame;
220 }
221
222 for (n = 0; n < framesToDecode; n++) {
223 lostFlag = !((ulFlags >> n) & 1);
224
225 retVal = Gecko2Decode(pDec->pDecoder, inBuf, lostFlag, (INT16 *)outBuf, ulTimeStamp);
226
227 if (retVal != 0) {
228 retVal = HXR_FAIL;
229 break;
230 }
231
232 inBuf += pDec->ulFrameSize;
233 *pNumBytesConsumed += pDec->ulFrameSize;
234 outBuf += pDec->ulSamplesPerFrame;
235 *pNumSamplesOut += pDec->ulSamplesPerFrame;
236 }
237 }
238
239 /* Discard invalid output samples */
240 if (retVal == HXR_FAIL) { /* decoder error */
241 *pNumSamplesOut = 0;
242 /* protect consumer ears by zeroing the output buffer,
243 just in case the error return code is disregarded. */
244 memset(pSamplesOut, 0, pDec->ulSamplesPerFrame * framesToDecode * sizeof(UINT16));
245 } else if (pDec->ulDelayRemaining > 0) { /* delay samples */
246 if (pDec->ulDelayRemaining >= *pNumSamplesOut) {
247 pDec->ulDelayRemaining -= *pNumSamplesOut;
248 *pNumSamplesOut = 0;
249 } else {
250 *pNumSamplesOut -= pDec->ulDelayRemaining;
251 memmove(pSamplesOut, pSamplesOut + pDec->ulDelayRemaining, *pNumSamplesOut);
252 pDec->ulDelayRemaining = 0;
253 }
254 }
255
256 return retVal;
257}
258
259HX_RESULT
260ra8lbr_decode_getmaxsize(void* pDecode,
261 UINT32* pNumSamples)
262{
263 ra8lbr_decode* pDec = (ra8lbr_decode *)pDecode;
264 *pNumSamples = pDec->ulSamplesPerFrame * pDec->ulFramesPerBlock;
265
266 return HXR_OK;
267}
268
269HX_RESULT
270ra8lbr_decode_getchannels(void* pDecode,
271 UINT32* pNumChannels)
272{
273 ra8lbr_decode* pDec = (ra8lbr_decode *)pDecode;
274 *pNumChannels = pDec->ulNumChannels;
275
276 return HXR_OK;
277}
278
279HX_RESULT
280ra8lbr_decode_getchannelmask(void* pDecode,
281 UINT32* pChannelMask)
282{
283 ra8lbr_decode* pDec = (ra8lbr_decode *)pDecode;
284 *pChannelMask = pDec->ulChannelMask;
285 return HXR_OK;
286}
287
288HX_RESULT
289ra8lbr_decode_getrate(void* pDecode,
290 UINT32* pSampleRate)
291{
292 ra8lbr_decode* pDec = (ra8lbr_decode *)pDecode;
293 *pSampleRate = pDec->ulSampleRate;
294
295 return HXR_OK;
296}
297
298HX_RESULT
299ra8lbr_decode_getdelay(void* pDecode,
300 UINT32* pNumSamples)
301{
302 ra8lbr_decode* pDec = (ra8lbr_decode *)pDecode;
303 /* delay compensation is handled internally */
304 *pNumSamples = 0;
305
306 return HXR_OK;
307}
308
309HX_RESULT
310ra8lbr_decode_close(void* pDecode,
311 void* pUserMem,
312 rm_free_func_ptr fpFree)
313{
314 ra8lbr_decode* pDec = (ra8lbr_decode *)pDecode;
315 /* free the ra8lbr decoder */
316 if (pDec->pDecoder) {
317 Gecko2FreeDecoder(pDec->pDecoder);
318 }
319 /* free the dummy input buffer */
320 if (pDec->pFlushData) {
321 fpFree(pUserMem, pDec->pFlushData);
322 }
323 /* free the ra8lbr backend */
324 fpFree(pUserMem, pDec);
325
326 return HXR_OK;
327}
328
329HX_RESULT
330ra8lbr_unpack_opaque_data(ra8lbr_data* pData,
331 UINT8* pBuf,
332 UINT32 ulLength)
333{
334 HX_RESULT retVal = HXR_FAIL;
335 UINT8* off = pBuf;
336
337 if (pBuf != HXNULL && ulLength != 0) {
338 retVal = HXR_OK;
339
340 pData->version = ((INT32) * off++) << 24;
341 pData->version |= ((INT32) * off++) << 16;
342 pData->version |= ((INT32) * off++) << 8;
343 pData->version |= ((INT32) * off++);
344
345 pData->nSamples = *off++ << 8;
346 pData->nSamples |= *off++;
347
348 pData->nRegions = *off++ << 8;
349 pData->nRegions |= *off++;
350 //printk("version %d, sample per frame %d \n",pData->version,pData->nSamples);
351 if (pData->version >= GECKO_VERSION) {
352 pData->delay = ((INT32) * off++) << 24;
353 pData->delay |= ((INT32) * off++) << 16;
354 pData->delay |= ((INT32) * off++) << 8;
355 pData->delay |= ((INT32) * off++);
356
357 pData->cplStart = *off++ << 8;
358 pData->cplStart |= *off++;
359
360 pData->cplQBits = *off++ << 8;
361 pData->cplQBits |= *off++;
362 } else {
363 /* the fixed point ra8lbr decoder supports dual-mono decoding with
364 a single decoder instance if cplQBits is set to zero. */
365 pData->cplStart = 0;
366 pData->cplQBits = 0;
367 }
368
369 if (pData->version == GECKO_MC1_VERSION) {
370 pData->channelMask = ((INT32) * off++) << 24;
371 pData->channelMask |= ((INT32) * off++) << 16;
372 pData->channelMask |= ((INT32) * off++) << 8;
373 pData->channelMask |= ((INT32) * off++);
374 }
375 }
376
377 return retVal;
378}
379