annotate alacenc.c @ 12043:f9a0bd0888a4 libavcodec

mpegaudio: call ff_mpegaudiodec_init_mmx() only from float decoder The mmx code is floating-point only, and this function does not know from which decoder it is called. Without this change, the integer decoder only "works" because the size of the context struct is smaller in this case, and the mmx init function writes the function pointer outside the allocated context.
author mru
date Thu, 01 Jul 2010 23:21:17 +0000
parents 01fe2ac0c8ac
children e59926e2c50c
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
7595
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
1 /**
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
2 * ALAC audio encoder
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
3 * Copyright (c) 2008 Jaikrishnan Menon <realityman@gmx.net>
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
4 *
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
5 * This file is part of FFmpeg.
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
6 *
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
11 *
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
15 * Lesser General Public License for more details.
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
16 *
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
20 */
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
21
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
22 #include "avcodec.h"
9411
4cb7c65fc775 Split bitstream.h, put the bitstream writer stuff in the new file
stefano
parents: 9110
diff changeset
23 #include "put_bits.h"
7595
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
24 #include "dsputil.h"
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
25 #include "lpc.h"
9110
ac31a0265eb9 Use sign_extend().
benoit
parents: 8261
diff changeset
26 #include "mathops.h"
7595
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
27
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
28 #define DEFAULT_FRAME_SIZE 4096
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
29 #define DEFAULT_SAMPLE_SIZE 16
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
30 #define MAX_CHANNELS 8
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
31 #define ALAC_EXTRADATA_SIZE 36
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
32 #define ALAC_FRAME_HEADER_SIZE 55
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
33 #define ALAC_FRAME_FOOTER_SIZE 3
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
34
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
35 #define ALAC_ESCAPE_CODE 0x1FF
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
36 #define ALAC_MAX_LPC_ORDER 30
7604
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
37 #define DEFAULT_MAX_PRED_ORDER 6
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
38 #define DEFAULT_MIN_PRED_ORDER 4
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
39 #define ALAC_MAX_LPC_PRECISION 9
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
40 #define ALAC_MAX_LPC_SHIFT 9
7595
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
41
7617
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
42 #define ALAC_CHMODE_LEFT_RIGHT 0
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
43 #define ALAC_CHMODE_LEFT_SIDE 1
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
44 #define ALAC_CHMODE_RIGHT_SIDE 2
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
45 #define ALAC_CHMODE_MID_SIDE 3
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
46
7604
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
47 typedef struct RiceContext {
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
48 int history_mult;
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
49 int initial_history;
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
50 int k_modifier;
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
51 int rice_modifier;
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
52 } RiceContext;
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 LPCContext {
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
55 int lpc_order;
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
56 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
57 int lpc_quant;
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
58 } LPCContext;
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
59
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
60 typedef struct AlacEncodeContext {
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
61 int compression_level;
7617
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
62 int min_prediction_order;
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
63 int max_prediction_order;
7604
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
64 int max_coded_frame_size;
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
65 int write_sample_size;
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
66 int32_t sample_buf[MAX_CHANNELS][DEFAULT_FRAME_SIZE];
7617
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
67 int32_t predictor_buf[DEFAULT_FRAME_SIZE];
7595
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
68 int interlacing_shift;
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
69 int interlacing_leftweight;
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
70 PutBitContext pbctx;
7604
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
71 RiceContext rc;
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
72 LPCContext lpc[MAX_CHANNELS];
7595
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
73 DSPContext dspctx;
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
74 AVCodecContext *avctx;
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
75 } AlacEncodeContext;
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
76
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
77
7604
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
78 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
79 {
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
80 int ch, i;
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
81
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
82 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
83 int16_t *sptr = input_samples + ch;
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
84 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
85 s->sample_buf[ch][i] = *sptr;
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
86 sptr += s->avctx->channels;
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
87 }
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
88 }
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
89 }
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
90
7595
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
91 static void encode_scalar(AlacEncodeContext *s, int x, int k, int write_sample_size)
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
92 {
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
93 int divisor, q, r;
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
94
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
95 k = FFMIN(k, s->rc.k_modifier);
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
96 divisor = (1<<k) - 1;
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
97 q = x / divisor;
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
98 r = x % divisor;
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
99
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
100 if(q > 8) {
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
101 // write escape code and sample value directly
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
102 put_bits(&s->pbctx, 9, ALAC_ESCAPE_CODE);
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
103 put_bits(&s->pbctx, write_sample_size, x);
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
104 } else {
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
105 if(q)
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
106 put_bits(&s->pbctx, q, (1<<q) - 1);
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
107 put_bits(&s->pbctx, 1, 0);
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
108
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
109 if(k != 1) {
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
110 if(r > 0)
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
111 put_bits(&s->pbctx, k, r+1);
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
112 else
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
113 put_bits(&s->pbctx, k-1, 0);
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
114 }
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
115 }
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
116 }
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
117
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
118 static void write_frame_header(AlacEncodeContext *s, int is_verbatim)
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
119 {
7604
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
120 put_bits(&s->pbctx, 3, s->avctx->channels-1); // No. of channels -1
7595
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
121 put_bits(&s->pbctx, 16, 0); // Seems to be zero
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
122 put_bits(&s->pbctx, 1, 1); // Sample count is in the header
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
123 put_bits(&s->pbctx, 2, 0); // FIXME: Wasted bytes field
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
124 put_bits(&s->pbctx, 1, is_verbatim); // Audio block is verbatim
10344
2b8a327189cd put_bits can only reliably write up to 31 bit bits, above it relies on
reimar
parents: 10173
diff changeset
125 put_bits32(&s->pbctx, s->avctx->frame_size); // No. of samples in the frame
7595
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
126 }
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
127
7617
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
128 static void calc_predictor_params(AlacEncodeContext *s, int ch)
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
129 {
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
130 int32_t coefs[MAX_LPC_ORDER][MAX_LPC_ORDER];
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
131 int shift[MAX_LPC_ORDER];
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
132 int opt_order;
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
133
10422
1c33160b0722 alacenc : use private compression_level value consistently.
jai_menon
parents: 10417
diff changeset
134 if (s->compression_level == 1) {
10417
952912ff616a alacenc : Move some code around for clarity.
jai_menon
parents: 10366
diff changeset
135 s->lpc[ch].lpc_order = 6;
952912ff616a alacenc : Move some code around for clarity.
jai_menon
parents: 10366
diff changeset
136 s->lpc[ch].lpc_quant = 6;
952912ff616a alacenc : Move some code around for clarity.
jai_menon
parents: 10366
diff changeset
137 s->lpc[ch].lpc_coeff[0] = 160;
952912ff616a alacenc : Move some code around for clarity.
jai_menon
parents: 10366
diff changeset
138 s->lpc[ch].lpc_coeff[1] = -190;
952912ff616a alacenc : Move some code around for clarity.
jai_menon
parents: 10366
diff changeset
139 s->lpc[ch].lpc_coeff[2] = 170;
952912ff616a alacenc : Move some code around for clarity.
jai_menon
parents: 10366
diff changeset
140 s->lpc[ch].lpc_coeff[3] = -130;
952912ff616a alacenc : Move some code around for clarity.
jai_menon
parents: 10366
diff changeset
141 s->lpc[ch].lpc_coeff[4] = 80;
952912ff616a alacenc : Move some code around for clarity.
jai_menon
parents: 10366
diff changeset
142 s->lpc[ch].lpc_coeff[5] = -25;
952912ff616a alacenc : Move some code around for clarity.
jai_menon
parents: 10366
diff changeset
143 } else {
10366
55f4c141dbb0 cosmetics: reindent and line wrap after last commit
jbr
parents: 10365
diff changeset
144 opt_order = ff_lpc_calc_coefs(&s->dspctx, s->sample_buf[ch],
55f4c141dbb0 cosmetics: reindent and line wrap after last commit
jbr
parents: 10365
diff changeset
145 s->avctx->frame_size,
55f4c141dbb0 cosmetics: reindent and line wrap after last commit
jbr
parents: 10365
diff changeset
146 s->min_prediction_order,
55f4c141dbb0 cosmetics: reindent and line wrap after last commit
jbr
parents: 10365
diff changeset
147 s->max_prediction_order,
55f4c141dbb0 cosmetics: reindent and line wrap after last commit
jbr
parents: 10365
diff changeset
148 ALAC_MAX_LPC_PRECISION, coefs, shift, 1,
55f4c141dbb0 cosmetics: reindent and line wrap after last commit
jbr
parents: 10365
diff changeset
149 ORDER_METHOD_EST, ALAC_MAX_LPC_SHIFT, 1);
7617
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
150
10366
55f4c141dbb0 cosmetics: reindent and line wrap after last commit
jbr
parents: 10365
diff changeset
151 s->lpc[ch].lpc_order = opt_order;
55f4c141dbb0 cosmetics: reindent and line wrap after last commit
jbr
parents: 10365
diff changeset
152 s->lpc[ch].lpc_quant = shift[opt_order-1];
55f4c141dbb0 cosmetics: reindent and line wrap after last commit
jbr
parents: 10365
diff changeset
153 memcpy(s->lpc[ch].lpc_coeff, coefs[opt_order-1], opt_order*sizeof(int));
10365
b44de7b79bee alacenc: add a fixed LPC coefficient mode as compression level 1. old
jbr
parents: 10344
diff changeset
154 }
7617
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
155 }
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
156
7604
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
157 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
158 {
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
159 int i, best;
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
160 int32_t lt, rt;
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
161 uint64_t sum[4];
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
162 uint64_t score[4];
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
163
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
164 /* 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
165 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
166 for(i=2; i<n; i++) {
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
167 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
168 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
169 sum[2] += FFABS((lt + rt) >> 1);
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
170 sum[3] += FFABS(lt - rt);
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
171 sum[0] += FFABS(lt);
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
172 sum[1] += FFABS(rt);
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
173 }
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
174
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
175 /* calculate score for each mode */
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
176 score[0] = sum[0] + sum[1];
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
177 score[1] = sum[0] + sum[3];
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
178 score[2] = sum[1] + sum[3];
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
179 score[3] = sum[2] + sum[3];
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
180
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
181 /* return mode with lowest score */
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
182 best = 0;
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
183 for(i=1; i<4; i++) {
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
184 if(score[i] < score[best]) {
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
185 best = i;
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
186 }
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
187 }
7617
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
188 return best;
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
189 }
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
190
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
191 static void alac_stereo_decorrelation(AlacEncodeContext *s)
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
192 {
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
193 int32_t *left = s->sample_buf[0], *right = s->sample_buf[1];
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
194 int i, mode, n = s->avctx->frame_size;
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
195 int32_t tmp;
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
196
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
197 mode = estimate_stereo_mode(left, right, n);
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
198
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
199 switch(mode)
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
200 {
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
201 case ALAC_CHMODE_LEFT_RIGHT:
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
202 s->interlacing_leftweight = 0;
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
203 s->interlacing_shift = 0;
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
204 break;
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
205
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
206 case ALAC_CHMODE_LEFT_SIDE:
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
207 for(i=0; i<n; i++) {
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
208 right[i] = left[i] - right[i];
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
209 }
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
210 s->interlacing_leftweight = 1;
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
211 s->interlacing_shift = 0;
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
212 break;
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
213
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
214 case ALAC_CHMODE_RIGHT_SIDE:
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
215 for(i=0; i<n; i++) {
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
216 tmp = right[i];
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
217 right[i] = left[i] - right[i];
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
218 left[i] = tmp + (right[i] >> 31);
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
219 }
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
220 s->interlacing_leftweight = 1;
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
221 s->interlacing_shift = 31;
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
222 break;
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
223
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
224 default:
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
225 for(i=0; i<n; i++) {
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
226 tmp = left[i];
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
227 left[i] = (tmp + right[i]) >> 1;
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
228 right[i] = tmp - right[i];
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
229 }
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
230 s->interlacing_leftweight = 1;
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
231 s->interlacing_shift = 1;
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
232 break;
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
233 }
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
234 }
7604
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
235
7619
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
236 static void alac_linear_predictor(AlacEncodeContext *s, int ch)
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
237 {
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
238 int i;
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
239 LPCContext lpc = s->lpc[ch];
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
240
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
241 if(lpc.lpc_order == 31) {
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
242 s->predictor_buf[0] = s->sample_buf[ch][0];
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
243
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
244 for(i=1; i<s->avctx->frame_size; i++)
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
245 s->predictor_buf[i] = s->sample_buf[ch][i] - s->sample_buf[ch][i-1];
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
246
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
247 return;
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
248 }
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
249
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
250 // generalised linear predictor
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
251
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
252 if(lpc.lpc_order > 0) {
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
253 int32_t *samples = s->sample_buf[ch];
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
254 int32_t *residual = s->predictor_buf;
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
255
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
256 // generate warm-up samples
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
257 residual[0] = samples[0];
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
258 for(i=1;i<=lpc.lpc_order;i++)
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
259 residual[i] = samples[i] - samples[i-1];
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
260
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
261 // perform lpc on remaining samples
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
262 for(i = lpc.lpc_order + 1; i < s->avctx->frame_size; i++) {
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
263 int sum = 1 << (lpc.lpc_quant - 1), res_val, j;
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
264
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
265 for (j = 0; j < lpc.lpc_order; j++) {
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
266 sum += (samples[lpc.lpc_order-j] - samples[0]) *
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
267 lpc.lpc_coeff[j];
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
268 }
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
269
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
270 sum >>= lpc.lpc_quant;
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
271 sum += samples[0];
9110
ac31a0265eb9 Use sign_extend().
benoit
parents: 8261
diff changeset
272 residual[i] = sign_extend(samples[lpc.lpc_order+1] - sum,
ac31a0265eb9 Use sign_extend().
benoit
parents: 8261
diff changeset
273 s->write_sample_size);
7619
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
274 res_val = residual[i];
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
275
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
276 if(res_val) {
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
277 int index = lpc.lpc_order - 1;
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
278 int neg = (res_val < 0);
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
279
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
280 while(index >= 0 && (neg ? (res_val < 0):(res_val > 0))) {
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
281 int val = samples[0] - samples[lpc.lpc_order - index];
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
282 int sign = (val ? FFSIGN(val) : 0);
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
283
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
284 if(neg)
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
285 sign*=-1;
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
286
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
287 lpc.lpc_coeff[index] -= sign;
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
288 val *= sign;
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
289 res_val -= ((val >> lpc.lpc_quant) *
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
290 (lpc.lpc_order - index));
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
291 index--;
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
292 }
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
293 }
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
294 samples++;
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
295 }
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
296 }
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
297 }
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
298
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
299 static void alac_entropy_coder(AlacEncodeContext *s)
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
300 {
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
301 unsigned int history = s->rc.initial_history;
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
302 int sign_modifier = 0, i, k;
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
303 int32_t *samples = s->predictor_buf;
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
304
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
305 for(i=0;i < s->avctx->frame_size;) {
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
306 int x;
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
307
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
308 k = av_log2((history >> 9) + 3);
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
309
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
310 x = -2*(*samples)-1;
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
311 x ^= (x>>31);
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
312
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
313 samples++;
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
314 i++;
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
315
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
316 encode_scalar(s, x - sign_modifier, k, s->write_sample_size);
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
317
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
318 history += x * s->rc.history_mult
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
319 - ((history * s->rc.history_mult) >> 9);
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
320
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
321 sign_modifier = 0;
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
322 if(x > 0xFFFF)
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
323 history = 0xFFFF;
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
324
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
325 if((history < 128) && (i < s->avctx->frame_size)) {
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
326 unsigned int block_size = 0;
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
327
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
328 k = 7 - av_log2(history) + ((history + 16) >> 6);
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
329
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
330 while((*samples == 0) && (i < s->avctx->frame_size)) {
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
331 samples++;
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
332 i++;
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
333 block_size++;
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
334 }
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
335 encode_scalar(s, block_size, k, 16);
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
336
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
337 sign_modifier = (block_size <= 0xFFFF);
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
338
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
339 history = 0;
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
340 }
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
341
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
342 }
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
343 }
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
344
7595
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
345 static void write_compressed_frame(AlacEncodeContext *s)
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
346 {
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
347 int i, j;
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
348
7659
b87a9296e854 alacenc : perform decorrelation only for stereo samples
jai_menon
parents: 7620
diff changeset
349 if(s->avctx->channels == 2)
b87a9296e854 alacenc : perform decorrelation only for stereo samples
jai_menon
parents: 7620
diff changeset
350 alac_stereo_decorrelation(s);
7595
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
351 put_bits(&s->pbctx, 8, s->interlacing_shift);
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
352 put_bits(&s->pbctx, 8, s->interlacing_leftweight);
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
353
7604
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
354 for(i=0;i<s->avctx->channels;i++) {
7595
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
355
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
356 calc_predictor_params(s, i);
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
357
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
358 put_bits(&s->pbctx, 4, 0); // prediction type : currently only type 0 has been RE'd
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
359 put_bits(&s->pbctx, 4, s->lpc[i].lpc_quant);
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
360
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
361 put_bits(&s->pbctx, 3, s->rc.rice_modifier);
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
362 put_bits(&s->pbctx, 5, s->lpc[i].lpc_order);
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
363 // predictor coeff. table
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
364 for(j=0;j<s->lpc[i].lpc_order;j++) {
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
365 put_sbits(&s->pbctx, 16, s->lpc[i].lpc_coeff[j]);
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
366 }
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
367 }
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
368
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
369 // apply lpc and entropy coding to audio samples
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
370
7604
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
371 for(i=0;i<s->avctx->channels;i++) {
7595
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
372 alac_linear_predictor(s, i);
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
373 alac_entropy_coder(s);
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
374 }
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
375 }
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
376
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
377 static av_cold int alac_encode_init(AVCodecContext *avctx)
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
378 {
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
379 AlacEncodeContext *s = avctx->priv_data;
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
380 uint8_t *alac_extradata = av_mallocz(ALAC_EXTRADATA_SIZE+1);
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
381
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
382 avctx->frame_size = DEFAULT_FRAME_SIZE;
7823
4525dcd81357 Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents: 7659
diff changeset
383 avctx->bits_per_coded_sample = DEFAULT_SAMPLE_SIZE;
7595
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
384
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
385 if(avctx->sample_fmt != SAMPLE_FMT_S16) {
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
386 av_log(avctx, AV_LOG_ERROR, "only pcm_s16 input samples are supported\n");
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
387 return -1;
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
388 }
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
389
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
390 // Set default compression level
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
391 if(avctx->compression_level == FF_COMPRESSION_DEFAULT)
10365
b44de7b79bee alacenc: add a fixed LPC coefficient mode as compression level 1. old
jbr
parents: 10344
diff changeset
392 s->compression_level = 2;
7595
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
393 else
10365
b44de7b79bee alacenc: add a fixed LPC coefficient mode as compression level 1. old
jbr
parents: 10344
diff changeset
394 s->compression_level = av_clip(avctx->compression_level, 0, 2);
7595
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
395
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
396 // Initialize default Rice parameters
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
397 s->rc.history_mult = 40;
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
398 s->rc.initial_history = 10;
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
399 s->rc.k_modifier = 14;
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
400 s->rc.rice_modifier = 4;
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
401
10173
f55ca9a2b948 Fix max_coded_frame_size computation to account for byte alignment.
jai_menon
parents: 9428
diff changeset
402 s->max_coded_frame_size = 8 + (avctx->frame_size*avctx->channels*avctx->bits_per_coded_sample>>3);
7595
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
403
7823
4525dcd81357 Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents: 7659
diff changeset
404 s->write_sample_size = avctx->bits_per_coded_sample + avctx->channels - 1; // FIXME: consider wasted_bytes
7595
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
405
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
406 AV_WB32(alac_extradata, ALAC_EXTRADATA_SIZE);
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
407 AV_WB32(alac_extradata+4, MKBETAG('a','l','a','c'));
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
408 AV_WB32(alac_extradata+12, avctx->frame_size);
7823
4525dcd81357 Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents: 7659
diff changeset
409 AV_WB8 (alac_extradata+17, avctx->bits_per_coded_sample);
7604
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
410 AV_WB8 (alac_extradata+21, avctx->channels);
7595
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
411 AV_WB32(alac_extradata+24, s->max_coded_frame_size);
7823
4525dcd81357 Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents: 7659
diff changeset
412 AV_WB32(alac_extradata+28, avctx->sample_rate*avctx->channels*avctx->bits_per_coded_sample); // average bitrate
7604
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
413 AV_WB32(alac_extradata+32, avctx->sample_rate);
7595
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
414
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
415 // Set relevant extradata fields
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
416 if(s->compression_level > 0) {
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
417 AV_WB8(alac_extradata+18, s->rc.history_mult);
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
418 AV_WB8(alac_extradata+19, s->rc.initial_history);
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
419 AV_WB8(alac_extradata+20, s->rc.k_modifier);
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
420 }
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
421
7619
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
422 s->min_prediction_order = DEFAULT_MIN_PRED_ORDER;
7617
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
423 if(avctx->min_prediction_order >= 0) {
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
424 if(avctx->min_prediction_order < MIN_LPC_ORDER ||
7620
5c2299115d1f alacenc: compare against ALAC_MAX_LPC_ORDER instead of MAX_LPC_ORDER
jai_menon
parents: 7619
diff changeset
425 avctx->min_prediction_order > ALAC_MAX_LPC_ORDER) {
7617
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
426 av_log(avctx, AV_LOG_ERROR, "invalid min prediction order: %d\n", avctx->min_prediction_order);
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
427 return -1;
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
428 }
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
429
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
430 s->min_prediction_order = avctx->min_prediction_order;
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
431 }
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
432
7619
0753d03d232a alacenc: last few hunks approved by michael
jai_menon
parents: 7618
diff changeset
433 s->max_prediction_order = DEFAULT_MAX_PRED_ORDER;
7617
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
434 if(avctx->max_prediction_order >= 0) {
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
435 if(avctx->max_prediction_order < MIN_LPC_ORDER ||
7620
5c2299115d1f alacenc: compare against ALAC_MAX_LPC_ORDER instead of MAX_LPC_ORDER
jai_menon
parents: 7619
diff changeset
436 avctx->max_prediction_order > ALAC_MAX_LPC_ORDER) {
7617
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
437 av_log(avctx, AV_LOG_ERROR, "invalid max prediction order: %d\n", avctx->max_prediction_order);
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
438 return -1;
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
439 }
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
440
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
441 s->max_prediction_order = avctx->max_prediction_order;
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
442 }
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
443
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
444 if(s->max_prediction_order < s->min_prediction_order) {
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
445 av_log(avctx, AV_LOG_ERROR, "invalid prediction orders: min=%d max=%d\n",
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
446 s->min_prediction_order, s->max_prediction_order);
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
447 return -1;
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
448 }
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
449
7595
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
450 avctx->extradata = alac_extradata;
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
451 avctx->extradata_size = ALAC_EXTRADATA_SIZE;
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
452
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
453 avctx->coded_frame = avcodec_alloc_frame();
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
454 avctx->coded_frame->key_frame = 1;
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
455
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
456 s->avctx = avctx;
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
457 dsputil_init(&s->dspctx, avctx);
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
458
7604
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
459 return 0;
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
460 }
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
461
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
462 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
463 int buf_size, void *data)
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
464 {
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
465 AlacEncodeContext *s = avctx->priv_data;
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
466 PutBitContext *pb = &s->pbctx;
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
467 int i, out_bytes, verbatim_flag = 0;
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
468
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
469 if(avctx->frame_size > DEFAULT_FRAME_SIZE) {
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
470 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
471 return -1;
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
472 }
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
473
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
474 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
475 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
476 return -1;
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
477 }
7595
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
478
7617
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
479 verbatim:
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
480 init_put_bits(pb, frame, buf_size);
924dc060db81 Import more OKed parts of ALAC encoder from GSoC repo.
ramiro
parents: 7604
diff changeset
481
7604
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
482 if((s->compression_level == 0) || verbatim_flag) {
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
483 // Verbatim mode
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
484 int16_t *samples = data;
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
485 write_frame_header(s, 1);
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
486 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
487 put_sbits(pb, 16, *samples++);
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
488 }
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
489 } else {
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
490 init_sample_buffers(s, data);
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
491 write_frame_header(s, 0);
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
492 write_compressed_frame(s);
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
493 }
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
494
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
495 put_bits(pb, 3, 7);
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
496 flush_put_bits(pb);
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
497 out_bytes = put_bits_count(pb) >> 3;
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
498
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
499 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
500 /* frame too large. use verbatim mode */
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
501 if(verbatim_flag || (s->compression_level == 0)) {
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
502 /* still too large. must be an error. */
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
503 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
504 return -1;
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
505 }
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
506 verbatim_flag = 1;
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
507 goto verbatim;
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
508 }
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
509
6250ff63990b Import more ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents: 7598
diff changeset
510 return out_bytes;
7595
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
511 }
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
512
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
513 static av_cold int alac_encode_close(AVCodecContext *avctx)
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
514 {
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
515 av_freep(&avctx->extradata);
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
516 avctx->extradata_size = 0;
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
517 av_freep(&avctx->coded_frame);
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
518 return 0;
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
519 }
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
520
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
521 AVCodec alac_encoder = {
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
522 "alac",
11560
8a4984c5cacc Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents: 10422
diff changeset
523 AVMEDIA_TYPE_AUDIO,
7595
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
524 CODEC_ID_ALAC,
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
525 sizeof(AlacEncodeContext),
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
526 alac_encode_init,
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
527 alac_encode_frame,
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
528 alac_encode_close,
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
529 .capabilities = CODEC_CAP_SMALL_LAST_FRAME,
11594
7942a09aac64 alacenc : Report supported input sample formats.
jai_menon
parents: 11560
diff changeset
530 .sample_fmts = (const enum SampleFormat[]){ SAMPLE_FMT_S16, SAMPLE_FMT_NONE},
7598
60dd0089cdba alacenc: NULL_IF_CONFIG_SMALL long_name.
ramiro
parents: 7595
diff changeset
531 .long_name = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"),
7595
30af3a9775de Import ok'd parts of ALAC encoder from GSoC repo.
ramiro
parents:
diff changeset
532 };