source: titan/libdreamdvd/a52_dec.c @ 39001

Last change on this file since 39001 was 14963, checked in by nit, 12 years ago

[titan] change to unix format

File size: 3.8 KB
Line 
1/*
2 * DreamDVD V0.9 - DVD-Player for Dreambox
3 * Copyright (C) 2007 by Seddi
4 *
5 * This DVD Player is based upon the great work from the libdvdnav project,
6 * a52dec library, ffmpeg and the knowledge from all the people who made
7 * watching DVD within linux possible.
8 *
9 * DreamDVD is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * DreamDVD is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
22 *
23 * part of libdreamdvd
24 */
25
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29
30#include <errno.h>
31#include <getopt.h>
32#include <math.h>
33#include <inttypes.h>
34#include <dlfcn.h>
35
36
37#include "a52dec.h"
38
39
40// try to dynamically load and wrap liba52.so.0
41
42int ddvd_load_liba52()
43{
44        a52_handle = dlopen("liba52.so.0",RTLD_LAZY);
45       
46        if (a52_handle)
47        {
48                a52_init = (a52_state_t* (*)(uint32_t)) dlsym(a52_handle, "a52_init");
49                a52_samples = (sample_t* (*)(a52_state_t*)) dlsym(a52_handle, "a52_samples");
50                a52_syncinfo = (int (*)(uint8_t*, int*, int*, int*)) dlsym(a52_handle, "a52_syncinfo");
51                a52_frame = (int (*)(a52_state_t* ,uint8_t* ,int* ,level_t* ,sample_t)) dlsym(a52_handle, "a52_frame");
52                a52_block = (int (*)(a52_state_t*)) dlsym(a52_handle, "a52_block");
53                a52_free = (void (*)(a52_state_t*)) dlsym(a52_handle, "a52_free");
54
55                printf("libdreamdvd: soft ac3 decoding is available, liba52.so.0 loaded !\n");
56                return 1;
57        }
58        else
59        {
60                printf("libdreamdvd: soft ac3 decoding is not available, liba52.so.0 not found !\n");
61                return 0;
62        }
63}
64
65// close dynamically loaded liba52.so.0
66
67void ddvd_close_liba52()
68{
69        dlclose(a52_handle);
70}
71
72// convert 32bit samples to 16bit
73
74static inline int16_t a52_convert (int32_t i)
75{
76    i >>= 15;
77    return (i > 32767) ? 32767 : ((i < -32768) ? -32768 : i);
78}
79
80// liba52 gives us 256 samples left - 256 samples right
81// we need 1 left - 1 right so lets sort them
82
83static void a52_convert2s16_2 (sample_t * _f, int16_t * s16)
84{
85    int i;
86    int32_t * f = (int32_t *) _f;
87
88    for (i = 0; i < 256; i++) {
89        s16[2*i] = a52_convert (f[i]);
90        s16[2*i+1] = a52_convert (f[i+256]);
91    }
92}
93
94// a52 decode function (needs liba52)
95
96int ddvd_ac3_decode(const uint8_t *input, unsigned int len, int16_t *output)
97{
98        static int sample_rate;
99    static int flags;
100    int bit_rate;
101        int out_len=0;
102        const uint8_t *end;
103        end=input+len;
104       
105    static uint8_t buf[3840];
106    static uint8_t * bufptr = buf;
107    static uint8_t * bufpos = buf + 7;
108
109    while (1) {
110        len = end - input;
111        if (!len)
112            break;
113        if (len > bufpos - bufptr)
114            len = bufpos - bufptr;
115       
116        memcpy (bufptr, input, len);
117        bufptr += len;
118        input += len;
119
120        if (bufptr == bufpos) {
121            if (bufpos == buf + 7) {
122                int length;
123
124                length = a52_syncinfo (buf, &flags, &sample_rate, &bit_rate);
125                if (!length) {
126                    for (bufptr = buf; bufptr < buf + 6; bufptr++)
127                        bufptr[0] = bufptr[1];
128                    continue;
129                }
130                bufpos = buf + length;
131            } else {
132                level_t level;
133                sample_t bias;
134                int i;
135
136                flags=A52_DOLBY|A52_ADJUST_LEVEL;
137                       
138                bias=0;
139                level=(1 << 26);
140
141                if (a52_frame (state, buf, &flags, &level, bias))
142                    goto error;
143
144                for (i = 0; i < 6; i++) {
145                    if (a52_block (state))
146                        goto error;
147                        a52_convert2s16_2(a52_samples(state),output);
148                        output+=512;
149                        out_len+=1024;
150                }
151                bufptr = buf;
152                bufpos = buf + 7;
153                continue;
154            error:
155                bufptr = buf;
156                bufpos = buf + 7;
157            }
158        }
159    }
160        return out_len;
161}
Note: See TracBrowser for help on using the repository browser.