Mercurial > libavcodec.hg
annotate alacenc.c @ 7605:681e7430fbeb libavcodec
Add okayed parts for AAC encoder
author | kostya |
---|---|
date | Mon, 18 Aug 2008 05:38:26 +0000 |
parents | 6250ff63990b |
children | 924dc060db81 |
rev | line source |
---|---|
7595 | 1 /** |
2 * ALAC audio encoder | |
3 * Copyright (c) 2008 Jaikrishnan Menon <realityman@gmx.net> | |
4 * | |
5 * This file is part of FFmpeg. | |
6 * | |
7 * FFmpeg is free software; you can redistribute it and/or | |
8 * modify it under the terms of the GNU Lesser General Public | |
9 * License as published by the Free Software Foundation; either | |
10 * version 2.1 of the License, or (at your option) any later version. | |
11 * | |
12 * FFmpeg is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
18 * License along with FFmpeg; if not, write to the Free Software | |
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
20 */ | |
21 | |
22 #include "avcodec.h" | |
23 #include "bitstream.h" | |
24 #include "dsputil.h" | |
25 #include "lpc.h" | |
26 | |
27 #define DEFAULT_FRAME_SIZE 4096 | |
28 #define DEFAULT_SAMPLE_SIZE 16 | |
29 #define MAX_CHANNELS 8 | |
30 #define ALAC_EXTRADATA_SIZE 36 | |
31 #define ALAC_FRAME_HEADER_SIZE 55 | |
32 #define ALAC_FRAME_FOOTER_SIZE 3 | |
33 | |
34 #define ALAC_ESCAPE_CODE 0x1FF | |
35 #define ALAC_MAX_LPC_ORDER 30 | |
7604
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
36 #define DEFAULT_MAX_PRED_ORDER 6 |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
37 #define DEFAULT_MIN_PRED_ORDER 4 |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
38 #define ALAC_MAX_LPC_PRECISION 9 |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
39 #define ALAC_MAX_LPC_SHIFT 9 |
7595 | 40 |
7604
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
41 typedef struct RiceContext { |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
42 int history_mult; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
43 int initial_history; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
44 int k_modifier; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
45 int rice_modifier; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
46 } RiceContext; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
47 |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
48 typedef struct LPCContext { |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
49 int lpc_order; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
50 int lpc_coeff[ALAC_MAX_LPC_ORDER+1]; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
51 int lpc_quant; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
52 } LPCContext; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
53 |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
54 typedef struct AlacEncodeContext { |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
55 int compression_level; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
56 int max_coded_frame_size; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
57 int write_sample_size; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
58 int32_t sample_buf[MAX_CHANNELS][DEFAULT_FRAME_SIZE]; |
7595 | 59 int interlacing_shift; |
60 int interlacing_leftweight; | |
61 PutBitContext pbctx; | |
7604
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
62 RiceContext rc; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
63 LPCContext lpc[MAX_CHANNELS]; |
7595 | 64 DSPContext dspctx; |
65 AVCodecContext *avctx; | |
66 } AlacEncodeContext; | |
67 | |
68 | |
7604
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
69 static void init_sample_buffers(AlacEncodeContext *s, int16_t *input_samples) |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
70 { |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
71 int ch, i; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
72 |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
73 for(ch=0;ch<s->avctx->channels;ch++) { |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
74 int16_t *sptr = input_samples + ch; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
75 for(i=0;i<s->avctx->frame_size;i++) { |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
76 s->sample_buf[ch][i] = *sptr; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
77 sptr += s->avctx->channels; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
78 } |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
79 } |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
80 } |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
81 |
7595 | 82 static void encode_scalar(AlacEncodeContext *s, int x, int k, int write_sample_size) |
83 { | |
84 int divisor, q, r; | |
85 | |
86 k = FFMIN(k, s->rc.k_modifier); | |
87 divisor = (1<<k) - 1; | |
88 q = x / divisor; | |
89 r = x % divisor; | |
90 | |
91 if(q > 8) { | |
92 // write escape code and sample value directly | |
93 put_bits(&s->pbctx, 9, ALAC_ESCAPE_CODE); | |
94 put_bits(&s->pbctx, write_sample_size, x); | |
95 } else { | |
96 if(q) | |
97 put_bits(&s->pbctx, q, (1<<q) - 1); | |
98 put_bits(&s->pbctx, 1, 0); | |
99 | |
100 if(k != 1) { | |
101 if(r > 0) | |
102 put_bits(&s->pbctx, k, r+1); | |
103 else | |
104 put_bits(&s->pbctx, k-1, 0); | |
105 } | |
106 } | |
107 } | |
108 | |
109 static void write_frame_header(AlacEncodeContext *s, int is_verbatim) | |
110 { | |
7604
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
111 put_bits(&s->pbctx, 3, s->avctx->channels-1); // No. of channels -1 |
7595 | 112 put_bits(&s->pbctx, 16, 0); // Seems to be zero |
113 put_bits(&s->pbctx, 1, 1); // Sample count is in the header | |
114 put_bits(&s->pbctx, 2, 0); // FIXME: Wasted bytes field | |
115 put_bits(&s->pbctx, 1, is_verbatim); // Audio block is verbatim | |
116 put_bits(&s->pbctx, 32, s->avctx->frame_size); // No. of samples in the frame | |
117 } | |
118 | |
7604
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
119 static int estimate_stereo_mode(int32_t *left_ch, int32_t *right_ch, int n) |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
120 { |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
121 int i, best; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
122 int32_t lt, rt; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
123 uint64_t sum[4]; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
124 uint64_t score[4]; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
125 |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
126 /* calculate sum of 2nd order residual for each channel */ |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
127 sum[0] = sum[1] = sum[2] = sum[3] = 0; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
128 for(i=2; i<n; i++) { |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
129 lt = left_ch[i] - 2*left_ch[i-1] + left_ch[i-2]; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
130 rt = right_ch[i] - 2*right_ch[i-1] + right_ch[i-2]; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
131 sum[2] += FFABS((lt + rt) >> 1); |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
132 sum[3] += FFABS(lt - rt); |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
133 sum[0] += FFABS(lt); |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
134 sum[1] += FFABS(rt); |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
135 } |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
136 |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
137 /* calculate score for each mode */ |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
138 score[0] = sum[0] + sum[1]; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
139 score[1] = sum[0] + sum[3]; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
140 score[2] = sum[1] + sum[3]; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
141 score[3] = sum[2] + sum[3]; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
142 |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
143 /* return mode with lowest score */ |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
144 best = 0; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
145 for(i=1; i<4; i++) { |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
146 if(score[i] < score[best]) { |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
147 best = i; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
148 } |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
149 } |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
150 |
7595 | 151 static void write_compressed_frame(AlacEncodeContext *s) |
152 { | |
153 int i, j; | |
154 | |
155 /* only simple mid/side decorrelation supported as of now */ | |
156 alac_stereo_decorrelation(s); | |
157 put_bits(&s->pbctx, 8, s->interlacing_shift); | |
158 put_bits(&s->pbctx, 8, s->interlacing_leftweight); | |
159 | |
7604
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
160 for(i=0;i<s->avctx->channels;i++) { |
7595 | 161 |
162 calc_predictor_params(s, i); | |
163 | |
164 put_bits(&s->pbctx, 4, 0); // prediction type : currently only type 0 has been RE'd | |
165 put_bits(&s->pbctx, 4, s->lpc[i].lpc_quant); | |
166 | |
167 put_bits(&s->pbctx, 3, s->rc.rice_modifier); | |
168 put_bits(&s->pbctx, 5, s->lpc[i].lpc_order); | |
169 // predictor coeff. table | |
170 for(j=0;j<s->lpc[i].lpc_order;j++) { | |
171 put_sbits(&s->pbctx, 16, s->lpc[i].lpc_coeff[j]); | |
172 } | |
173 } | |
174 | |
175 // apply lpc and entropy coding to audio samples | |
176 | |
7604
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
177 for(i=0;i<s->avctx->channels;i++) { |
7595 | 178 alac_linear_predictor(s, i); |
179 alac_entropy_coder(s); | |
180 } | |
181 } | |
182 | |
183 static av_cold int alac_encode_init(AVCodecContext *avctx) | |
184 { | |
185 AlacEncodeContext *s = avctx->priv_data; | |
186 uint8_t *alac_extradata = av_mallocz(ALAC_EXTRADATA_SIZE+1); | |
187 | |
188 avctx->frame_size = DEFAULT_FRAME_SIZE; | |
189 avctx->bits_per_sample = DEFAULT_SAMPLE_SIZE; | |
190 | |
191 if(avctx->sample_fmt != SAMPLE_FMT_S16) { | |
192 av_log(avctx, AV_LOG_ERROR, "only pcm_s16 input samples are supported\n"); | |
193 return -1; | |
194 } | |
195 | |
196 // Set default compression level | |
197 if(avctx->compression_level == FF_COMPRESSION_DEFAULT) | |
198 s->compression_level = 1; | |
199 else | |
200 s->compression_level = av_clip(avctx->compression_level, 0, 1); | |
201 | |
202 // Initialize default Rice parameters | |
203 s->rc.history_mult = 40; | |
204 s->rc.initial_history = 10; | |
205 s->rc.k_modifier = 14; | |
206 s->rc.rice_modifier = 4; | |
207 | |
208 s->max_coded_frame_size = (ALAC_FRAME_HEADER_SIZE + ALAC_FRAME_FOOTER_SIZE + | |
7604
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
209 avctx->frame_size*avctx->channels*avctx->bits_per_sample)>>3; |
7595 | 210 |
7604
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
211 s->write_sample_size = avctx->bits_per_sample + avctx->channels - 1; // FIXME: consider wasted_bytes |
7595 | 212 |
213 AV_WB32(alac_extradata, ALAC_EXTRADATA_SIZE); | |
214 AV_WB32(alac_extradata+4, MKBETAG('a','l','a','c')); | |
215 AV_WB32(alac_extradata+12, avctx->frame_size); | |
216 AV_WB8 (alac_extradata+17, avctx->bits_per_sample); | |
7604
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
217 AV_WB8 (alac_extradata+21, avctx->channels); |
7595 | 218 AV_WB32(alac_extradata+24, s->max_coded_frame_size); |
7604
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
219 AV_WB32(alac_extradata+28, avctx->sample_rate*avctx->channels*avctx->bits_per_sample); // average bitrate |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
220 AV_WB32(alac_extradata+32, avctx->sample_rate); |
7595 | 221 |
222 // Set relevant extradata fields | |
223 if(s->compression_level > 0) { | |
224 AV_WB8(alac_extradata+18, s->rc.history_mult); | |
225 AV_WB8(alac_extradata+19, s->rc.initial_history); | |
226 AV_WB8(alac_extradata+20, s->rc.k_modifier); | |
227 } | |
228 | |
229 avctx->extradata = alac_extradata; | |
230 avctx->extradata_size = ALAC_EXTRADATA_SIZE; | |
231 | |
232 avctx->coded_frame = avcodec_alloc_frame(); | |
233 avctx->coded_frame->key_frame = 1; | |
234 | |
235 s->avctx = avctx; | |
236 dsputil_init(&s->dspctx, avctx); | |
237 | |
7604
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
238 return 0; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
239 } |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
240 |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
241 static int alac_encode_frame(AVCodecContext *avctx, uint8_t *frame, |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
242 int buf_size, void *data) |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
243 { |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
244 AlacEncodeContext *s = avctx->priv_data; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
245 PutBitContext *pb = &s->pbctx; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
246 int i, out_bytes, verbatim_flag = 0; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
247 |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
248 if(avctx->frame_size > DEFAULT_FRAME_SIZE) { |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
249 av_log(avctx, AV_LOG_ERROR, "input frame size exceeded\n"); |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
250 return -1; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
251 } |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
252 |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
253 if(buf_size < 2*s->max_coded_frame_size) { |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
254 av_log(avctx, AV_LOG_ERROR, "buffer size is too small\n"); |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
255 return -1; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
256 } |
7595 | 257 |
7604
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
258 if((s->compression_level == 0) || verbatim_flag) { |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
259 // Verbatim mode |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
260 int16_t *samples = data; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
261 write_frame_header(s, 1); |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
262 for(i=0; i<avctx->frame_size*avctx->channels; i++) { |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
263 put_sbits(pb, 16, *samples++); |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
264 } |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
265 } else { |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
266 init_sample_buffers(s, data); |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
267 write_frame_header(s, 0); |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
268 write_compressed_frame(s); |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
269 } |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
270 |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
271 put_bits(pb, 3, 7); |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
272 flush_put_bits(pb); |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
273 out_bytes = put_bits_count(pb) >> 3; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
274 |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
275 if(out_bytes > s->max_coded_frame_size) { |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
276 /* frame too large. use verbatim mode */ |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
277 if(verbatim_flag || (s->compression_level == 0)) { |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
278 /* still too large. must be an error. */ |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
279 av_log(avctx, AV_LOG_ERROR, "error encoding frame\n"); |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
280 return -1; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
281 } |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
282 verbatim_flag = 1; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
283 goto verbatim; |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
284 } |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
285 |
6250ff63990b
Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
7598
diff
changeset
|
286 return out_bytes; |
7595 | 287 } |
288 | |
289 static av_cold int alac_encode_close(AVCodecContext *avctx) | |
290 { | |
291 av_freep(&avctx->extradata); | |
292 avctx->extradata_size = 0; | |
293 av_freep(&avctx->coded_frame); | |
294 return 0; | |
295 } | |
296 | |
297 AVCodec alac_encoder = { | |
298 "alac", | |
299 CODEC_TYPE_AUDIO, | |
300 CODEC_ID_ALAC, | |
301 sizeof(AlacEncodeContext), | |
302 alac_encode_init, | |
303 alac_encode_frame, | |
304 alac_encode_close, | |
305 .capabilities = CODEC_CAP_SMALL_LAST_FRAME, | |
7598 | 306 .long_name = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"), |
7595 | 307 }; |