Mercurial > libavcodec.hg
comparison ac3dec.c @ 314:289eb941b8ba libavcodec
* encoding of AC3 with more than 2 channels
by Takashi Iwai <tiwai@suse.de>
author | kabi |
---|---|
date | Mon, 08 Apr 2002 12:08:03 +0000 |
parents | 5aa6292a1660 |
children | 21697f35a9ca |
comparison
equal
deleted
inserted
replaced
313:a0124152c89d | 314:289eb941b8ba |
---|---|
24 typedef struct AC3DecodeState { | 24 typedef struct AC3DecodeState { |
25 UINT8 inbuf[4096]; /* input buffer */ | 25 UINT8 inbuf[4096]; /* input buffer */ |
26 UINT8 *inbuf_ptr; | 26 UINT8 *inbuf_ptr; |
27 int frame_size; | 27 int frame_size; |
28 int flags; | 28 int flags; |
29 int channels; | |
29 ac3_state_t state; | 30 ac3_state_t state; |
30 } AC3DecodeState; | 31 } AC3DecodeState; |
31 | 32 |
32 static int ac3_decode_init(AVCodecContext *avctx) | 33 static int ac3_decode_init(AVCodecContext *avctx) |
33 { | 34 { |
50 return -32768; | 51 return -32768; |
51 else | 52 else |
52 return i - 0x43c00000; | 53 return i - 0x43c00000; |
53 } | 54 } |
54 | 55 |
55 static inline void float_to_int (float * _f, INT16 * s16) | 56 static inline void float_to_int (float * _f, INT16 * s16, int nchannels) |
56 { | 57 { |
57 int i; | 58 int i, j, c; |
58 int32_t * f = (int32_t *) _f; // XXX assumes IEEE float format | 59 int32_t * f = (int32_t *) _f; // XXX assumes IEEE float format |
59 | 60 |
61 j = 0; | |
62 nchannels *= 256; | |
60 for (i = 0; i < 256; i++) { | 63 for (i = 0; i < 256; i++) { |
61 s16[2*i] = blah (f[i]); | 64 for (c = 0; c < nchannels; c += 256) |
62 s16[2*i+1] = blah (f[i+256]); | 65 s16[j++] = blah (f[i + c]); |
63 } | |
64 } | |
65 | |
66 static inline void float_to_int_mono (float * _f, INT16 * s16) | |
67 { | |
68 int i; | |
69 int32_t * f = (int32_t *) _f; // XXX assumes IEEE float format | |
70 | |
71 for (i = 0; i < 256; i++) { | |
72 s16[i] = blah (f[i]); | |
73 } | 66 } |
74 } | 67 } |
75 | 68 |
76 /**** end */ | 69 /**** end */ |
77 | 70 |
85 UINT8 *buf_ptr; | 78 UINT8 *buf_ptr; |
86 int flags, i, len; | 79 int flags, i, len; |
87 int sample_rate, bit_rate; | 80 int sample_rate, bit_rate; |
88 short *out_samples = data; | 81 short *out_samples = data; |
89 float level; | 82 float level; |
83 static int ac3_channels[8] = { | |
84 2, 1, 2, 3, 3, 4, 4, 5 | |
85 }; | |
90 | 86 |
91 *data_size = 0; | 87 *data_size = 0; |
92 buf_ptr = buf; | 88 buf_ptr = buf; |
93 while (buf_size > 0) { | 89 while (buf_size > 0) { |
94 len = s->inbuf_ptr - s->inbuf; | 90 len = s->inbuf_ptr - s->inbuf; |
109 s->inbuf_ptr--; | 105 s->inbuf_ptr--; |
110 } else { | 106 } else { |
111 s->frame_size = len; | 107 s->frame_size = len; |
112 /* update codec info */ | 108 /* update codec info */ |
113 avctx->sample_rate = sample_rate; | 109 avctx->sample_rate = sample_rate; |
114 if ((s->flags & AC3_CHANNEL_MASK) == AC3_MONO) | 110 s->channels = ac3_channels[s->flags & 7]; |
115 avctx->channels = 1; | 111 if (s->flags & AC3_LFE) |
116 else | 112 s->channels++; |
117 avctx->channels = 2; | 113 if (s->channels < avctx->channels) { |
114 fprintf(stderr, "Source channels are less than specified: output to %d channels..\n", s->channels); | |
115 avctx->channels = s->channels; | |
116 } | |
118 avctx->bit_rate = bit_rate; | 117 avctx->bit_rate = bit_rate; |
119 } | 118 } |
120 } | 119 } |
121 } else if (len < s->frame_size) { | 120 } else if (len < s->frame_size) { |
122 len = s->frame_size - len; | 121 len = s->frame_size - len; |
126 memcpy(s->inbuf_ptr, buf_ptr, len); | 125 memcpy(s->inbuf_ptr, buf_ptr, len); |
127 buf_ptr += len; | 126 buf_ptr += len; |
128 s->inbuf_ptr += len; | 127 s->inbuf_ptr += len; |
129 buf_size -= len; | 128 buf_size -= len; |
130 } else { | 129 } else { |
130 #if 0 | |
131 if (avctx->channels == 1) | 131 if (avctx->channels == 1) |
132 flags = AC3_MONO; | 132 flags = AC3_MONO; |
133 else | 133 else |
134 flags = AC3_STEREO; | 134 flags = AC3_STEREO; |
135 | 135 #else |
136 flags = s->flags; | |
137 #endif | |
136 flags |= AC3_ADJUST_LEVEL; | 138 flags |= AC3_ADJUST_LEVEL; |
137 level = 1; | 139 level = 1; |
138 if (ac3_frame (&s->state, s->inbuf, &flags, &level, 384)) { | 140 if (ac3_frame (&s->state, s->inbuf, &flags, &level, 384)) { |
139 fail: | 141 fail: |
140 s->inbuf_ptr = s->inbuf; | 142 s->inbuf_ptr = s->inbuf; |
142 continue; | 144 continue; |
143 } | 145 } |
144 for (i = 0; i < 6; i++) { | 146 for (i = 0; i < 6; i++) { |
145 if (ac3_block (&s->state)) | 147 if (ac3_block (&s->state)) |
146 goto fail; | 148 goto fail; |
147 if (avctx->channels == 1) | 149 float_to_int (*samples, out_samples + i * 256 * avctx->channels, avctx->channels); |
148 float_to_int_mono (*samples, out_samples + i * 256); | |
149 else | |
150 float_to_int (*samples, out_samples + i * 512); | |
151 } | 150 } |
152 s->inbuf_ptr = s->inbuf; | 151 s->inbuf_ptr = s->inbuf; |
153 s->frame_size = 0; | 152 s->frame_size = 0; |
154 *data_size = 6 * avctx->channels * 256 * sizeof(INT16); | 153 *data_size = 6 * avctx->channels * 256 * sizeof(INT16); |
155 break; | 154 break; |