annotate flacenc.c @ 3353:5b901881d6ed libavcodec

first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
author michael
date Sat, 24 Jun 2006 10:20:15 +0000
parents
children ba80e4de976b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1 /**
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
2 * FLAC audio encoder
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
3 * Copyright (c) 2006 Justin Ruggles <jruggle@earthlink.net>
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
4 *
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
5 * This library is free software; you can redistribute it and/or
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
6 * modify it under the terms of the GNU Lesser General Public
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
7 * License as published by the Free Software Foundation; either
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
8 * version 2 of the License, or (at your option) any later version.
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
9 *
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
10 * This library is distributed in the hope that it will be useful,
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
13 * Lesser General Public License for more details.
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
14 *
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
15 * You should have received a copy of the GNU Lesser General Public
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
16 * License along with this library; if not, write to the Free Software
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
18 */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
19
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
20 #include "avcodec.h"
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
21 #include "bitstream.h"
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
22 #include "crc.h"
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
23 #include "golomb.h"
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
24
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
25 #define FLAC_MAX_CH 8
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
26 #define FLAC_MIN_BLOCKSIZE 16
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
27 #define FLAC_MAX_BLOCKSIZE 65535
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
28
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
29 #define FLAC_SUBFRAME_CONSTANT 0
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
30 #define FLAC_SUBFRAME_VERBATIM 1
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
31 #define FLAC_SUBFRAME_FIXED 8
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
32 #define FLAC_SUBFRAME_LPC 32
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
33
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
34 #define FLAC_CHMODE_NOT_STEREO 0
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
35 #define FLAC_CHMODE_LEFT_RIGHT 1
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
36 #define FLAC_CHMODE_LEFT_SIDE 8
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
37 #define FLAC_CHMODE_RIGHT_SIDE 9
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
38 #define FLAC_CHMODE_MID_SIDE 10
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
39
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
40 #define FLAC_STREAMINFO_SIZE 34
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
41
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
42 typedef struct FlacSubframe {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
43 int type;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
44 int type_code;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
45 int obits;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
46 int order;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
47 int32_t samples[FLAC_MAX_BLOCKSIZE];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
48 int32_t residual[FLAC_MAX_BLOCKSIZE];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
49 } FlacSubframe;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
50
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
51 typedef struct FlacFrame {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
52 FlacSubframe subframes[FLAC_MAX_CH];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
53 int blocksize;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
54 int bs_code[2];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
55 uint8_t crc8;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
56 int ch_mode;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
57 } FlacFrame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
58
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
59 typedef struct FlacEncodeContext {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
60 PutBitContext pb;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
61 int channels;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
62 int ch_code;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
63 int samplerate;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
64 int sr_code[2];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
65 int blocksize;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
66 int max_framesize;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
67 uint32_t frame_count;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
68 FlacFrame frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
69 } FlacEncodeContext;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
70
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
71 static const int flac_samplerates[16] = {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
72 0, 0, 0, 0,
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
73 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000,
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
74 0, 0, 0, 0
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
75 };
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
76
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
77 static const int flac_blocksizes[16] = {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
78 0,
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
79 192,
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
80 576, 1152, 2304, 4608,
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
81 0, 0,
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
82 256, 512, 1024, 2048, 4096, 8192, 16384, 32768
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
83 };
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
84
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
85 static const int flac_blocksizes_ordered[14] = {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
86 0, 192, 256, 512, 576, 1024, 1152, 2048, 2304, 4096, 4608, 8192, 16384, 32768
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
87 };
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
88
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
89 /**
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
90 * Writes streaminfo metadata block to byte array
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
91 */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
92 static void write_streaminfo(FlacEncodeContext *s, uint8_t *header)
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
93 {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
94 PutBitContext pb;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
95
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
96 memset(header, 0, FLAC_STREAMINFO_SIZE);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
97 init_put_bits(&pb, header, FLAC_STREAMINFO_SIZE);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
98
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
99 /* streaminfo metadata block */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
100 put_bits(&pb, 16, s->blocksize);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
101 put_bits(&pb, 16, s->blocksize);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
102 put_bits(&pb, 24, 0);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
103 put_bits(&pb, 24, s->max_framesize);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
104 put_bits(&pb, 20, s->samplerate);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
105 put_bits(&pb, 3, s->channels-1);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
106 put_bits(&pb, 5, 15); /* bits per sample - 1 */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
107 flush_put_bits(&pb);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
108 /* total samples = 0 */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
109 /* MD5 signature = 0 */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
110 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
111
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
112 #define BLOCK_TIME_MS 105
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
113
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
114 /**
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
115 * Sets blocksize based on samplerate
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
116 * Chooses the closest predefined blocksize >= BLOCK_TIME_MS milliseconds
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
117 */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
118 static int select_blocksize(int samplerate)
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
119 {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
120 int i;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
121 int target;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
122 int blocksize;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
123
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
124 assert(samplerate > 0);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
125 blocksize = 0;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
126 target = (samplerate * BLOCK_TIME_MS) / 1000;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
127 for(i=13; i>=0; i--) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
128 if(target >= flac_blocksizes_ordered[i]) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
129 blocksize = flac_blocksizes_ordered[i];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
130 break;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
131 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
132 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
133 if(blocksize == 0) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
134 blocksize = flac_blocksizes_ordered[1];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
135 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
136 return blocksize;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
137 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
138
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
139 static int flac_encode_init(AVCodecContext *avctx)
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
140 {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
141 int freq = avctx->sample_rate;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
142 int channels = avctx->channels;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
143 FlacEncodeContext *s = avctx->priv_data;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
144 int i;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
145 uint8_t *streaminfo;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
146
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
147 if(s == NULL) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
148 return -1;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
149 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
150
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
151 if(avctx->sample_fmt != SAMPLE_FMT_S16) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
152 return -1;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
153 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
154
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
155 if(channels < 1 || channels > FLAC_MAX_CH) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
156 return -1;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
157 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
158 s->channels = channels;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
159 s->ch_code = s->channels-1;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
160
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
161 /* find samplerate in table */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
162 if(freq < 1)
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
163 return -1;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
164 for(i=4; i<12; i++) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
165 if(freq == flac_samplerates[i]) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
166 s->samplerate = flac_samplerates[i];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
167 s->sr_code[0] = i;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
168 s->sr_code[1] = 0;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
169 break;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
170 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
171 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
172 /* if not in table, samplerate is non-standard */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
173 if(i == 12) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
174 if(freq % 1000 == 0 && freq < 255000) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
175 s->sr_code[0] = 12;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
176 s->sr_code[1] = freq / 1000;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
177 } else if(freq % 10 == 0 && freq < 655350) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
178 s->sr_code[0] = 14;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
179 s->sr_code[1] = freq / 10;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
180 } else if(freq < 65535) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
181 s->sr_code[0] = 13;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
182 s->sr_code[1] = freq;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
183 } else {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
184 return -1;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
185 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
186 s->samplerate = freq;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
187 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
188
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
189 s->blocksize = select_blocksize(s->samplerate);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
190 avctx->frame_size = s->blocksize;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
191
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
192 s->max_framesize = 14 + (s->blocksize * s->channels * 2);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
193
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
194 streaminfo = av_malloc(FLAC_STREAMINFO_SIZE);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
195 write_streaminfo(s, streaminfo);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
196 avctx->extradata = streaminfo;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
197 avctx->extradata_size = FLAC_STREAMINFO_SIZE;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
198
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
199 s->frame_count = 0;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
200
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
201 avctx->coded_frame = avcodec_alloc_frame();
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
202 avctx->coded_frame->key_frame = 1;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
203
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
204 return 0;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
205 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
206
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
207 static int init_frame(FlacEncodeContext *s)
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
208 {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
209 int i, ch;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
210 FlacFrame *frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
211
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
212 frame = &s->frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
213
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
214 for(i=0; i<16; i++) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
215 if(s->blocksize == flac_blocksizes[i]) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
216 frame->blocksize = flac_blocksizes[i];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
217 frame->bs_code[0] = i;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
218 frame->bs_code[1] = 0;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
219 break;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
220 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
221 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
222 if(i == 16) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
223 frame->blocksize = s->blocksize;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
224 if(frame->blocksize <= 256) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
225 frame->bs_code[0] = 6;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
226 frame->bs_code[1] = frame->blocksize-1;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
227 } else {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
228 frame->bs_code[0] = 7;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
229 frame->bs_code[1] = frame->blocksize-1;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
230 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
231 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
232
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
233 for(ch=0; ch<s->channels; ch++) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
234 frame->subframes[ch].obits = 16;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
235 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
236 if(s->channels == 2) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
237 frame->ch_mode = FLAC_CHMODE_LEFT_RIGHT;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
238 } else {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
239 frame->ch_mode = FLAC_CHMODE_NOT_STEREO;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
240 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
241
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
242 return 0;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
243 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
244
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
245 /**
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
246 * Copy channel-interleaved input samples into separate subframes
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
247 */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
248 static void copy_samples(FlacEncodeContext *s, int16_t *samples)
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
249 {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
250 int i, j, ch;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
251 FlacFrame *frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
252
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
253 frame = &s->frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
254 for(i=0,j=0; i<frame->blocksize; i++) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
255 for(ch=0; ch<s->channels; ch++,j++) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
256 frame->subframes[ch].samples[i] = samples[j];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
257 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
258 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
259 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
260
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
261 static void encode_residual_verbatim(FlacEncodeContext *s, int ch)
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
262 {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
263 FlacFrame *frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
264 FlacSubframe *sub;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
265 int32_t *res;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
266 int32_t *smp;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
267 int n;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
268
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
269 frame = &s->frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
270 sub = &frame->subframes[ch];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
271 res = sub->residual;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
272 smp = sub->samples;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
273 n = frame->blocksize;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
274
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
275 sub->order = 0;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
276 sub->type = FLAC_SUBFRAME_VERBATIM;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
277 sub->type_code = sub->type;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
278
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
279 memcpy(res, smp, n * sizeof(int32_t));
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
280 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
281
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
282 static void encode_residual_fixed(int32_t *res, int32_t *smp, int n, int order)
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
283 {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
284 int i;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
285 int32_t pred;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
286
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
287 for(i=0; i<order; i++) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
288 res[i] = smp[i];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
289 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
290 for(i=order; i<n; i++) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
291 pred = 0;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
292 switch(order) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
293 case 0: pred = 0;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
294 break;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
295 case 1: pred = smp[i-1];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
296 break;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
297 case 2: pred = 2*smp[i-1] - smp[i-2];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
298 break;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
299 case 3: pred = 3*smp[i-1] - 3*smp[i-2] + smp[i-3];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
300 break;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
301 case 4: pred = 4*smp[i-1] - 6*smp[i-2] + 4*smp[i-3] - smp[i-4];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
302 break;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
303 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
304 res[i] = smp[i] - pred;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
305 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
306 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
307
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
308 static void encode_residual(FlacEncodeContext *s, int ch)
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
309 {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
310 FlacFrame *frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
311 FlacSubframe *sub;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
312 int32_t *res;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
313 int32_t *smp;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
314 int n;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
315
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
316 frame = &s->frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
317 sub = &frame->subframes[ch];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
318 res = sub->residual;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
319 smp = sub->samples;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
320 n = frame->blocksize;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
321
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
322 sub->order = 2;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
323 sub->type = FLAC_SUBFRAME_FIXED;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
324 sub->type_code = sub->type | sub->order;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
325 encode_residual_fixed(res, smp, n, sub->order);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
326 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
327
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
328 static void
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
329 put_sbits(PutBitContext *pb, int bits, int32_t val)
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
330 {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
331 uint32_t uval;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
332
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
333 assert(bits >= 0 && bits <= 31);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
334 uval = (val < 0) ? (1UL << bits) + val : val;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
335 put_bits(pb, bits, uval);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
336 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
337
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
338 static void
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
339 write_utf8(PutBitContext *pb, uint32_t val)
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
340 {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
341 int i, bytes, mask, shift;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
342
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
343 bytes = 1;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
344 if(val >= 0x80) bytes++;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
345 if(val >= 0x800) bytes++;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
346 if(val >= 0x10000) bytes++;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
347 if(val >= 0x200000) bytes++;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
348 if(val >= 0x4000000) bytes++;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
349
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
350 if(bytes == 1) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
351 put_bits(pb, 8, val);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
352 return;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
353 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
354
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
355 shift = (bytes - 1) * 6;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
356 mask = 0x80 + ((1 << 7) - (1 << (8 - bytes)));
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
357 put_bits(pb, 8, mask | (val >> shift));
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
358 for(i=0; i<bytes-1; i++) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
359 shift -= 6;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
360 put_bits(pb, 8, 0x80 | ((val >> shift) & 0x3F));
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
361 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
362 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
363
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
364 static void
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
365 output_frame_header(FlacEncodeContext *s)
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
366 {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
367 FlacFrame *frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
368 int crc;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
369
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
370 frame = &s->frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
371
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
372 put_bits(&s->pb, 16, 0xFFF8);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
373 put_bits(&s->pb, 4, frame->bs_code[0]);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
374 put_bits(&s->pb, 4, s->sr_code[0]);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
375 if(frame->ch_mode == FLAC_CHMODE_NOT_STEREO) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
376 put_bits(&s->pb, 4, s->ch_code);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
377 } else {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
378 put_bits(&s->pb, 4, frame->ch_mode);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
379 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
380 put_bits(&s->pb, 3, 4); /* bits-per-sample code */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
381 put_bits(&s->pb, 1, 0);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
382 write_utf8(&s->pb, s->frame_count);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
383 if(frame->bs_code[1] > 0) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
384 if(frame->bs_code[1] < 256) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
385 put_bits(&s->pb, 8, frame->bs_code[1]);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
386 } else {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
387 put_bits(&s->pb, 16, frame->bs_code[1]);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
388 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
389 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
390 if(s->sr_code[1] > 0) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
391 if(s->sr_code[1] < 256) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
392 put_bits(&s->pb, 8, s->sr_code[1]);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
393 } else {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
394 put_bits(&s->pb, 16, s->sr_code[1]);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
395 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
396 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
397 flush_put_bits(&s->pb);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
398 crc = av_crc(av_crc07, 0, s->pb.buf, put_bits_count(&s->pb)>>3);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
399 put_bits(&s->pb, 8, crc);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
400 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
401
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
402 static void output_subframe_verbatim(FlacEncodeContext *s, int ch)
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
403 {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
404 int i;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
405 FlacFrame *frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
406 FlacSubframe *sub;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
407 int32_t res;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
408
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
409 frame = &s->frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
410 sub = &frame->subframes[ch];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
411
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
412 for(i=0; i<frame->blocksize; i++) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
413 res = sub->residual[i];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
414 put_sbits(&s->pb, sub->obits, res);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
415 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
416 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
417
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
418 static void
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
419 output_residual(FlacEncodeContext *ctx, int ch)
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
420 {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
421 int i, j, p;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
422 int k, porder, psize, res_cnt;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
423 FlacFrame *frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
424 FlacSubframe *sub;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
425
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
426 frame = &ctx->frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
427 sub = &frame->subframes[ch];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
428
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
429 /* rice-encoded block */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
430 put_bits(&ctx->pb, 2, 0);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
431
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
432 /* partition order */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
433 porder = 0;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
434 psize = frame->blocksize;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
435 //porder = sub->rc.porder;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
436 //psize = frame->blocksize >> porder;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
437 put_bits(&ctx->pb, 4, porder);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
438 res_cnt = psize - sub->order;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
439
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
440 /* residual */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
441 j = sub->order;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
442 for(p=0; p<(1 << porder); p++) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
443 //k = sub->rc.params[p];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
444 k = 9;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
445 put_bits(&ctx->pb, 4, k);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
446 if(p == 1) res_cnt = psize;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
447 for(i=0; i<res_cnt && j<frame->blocksize; i++, j++) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
448 set_sr_golomb_flac(&ctx->pb, sub->residual[j], k, INT32_MAX, 0);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
449 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
450 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
451 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
452
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
453 static void
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
454 output_subframe_fixed(FlacEncodeContext *ctx, int ch)
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
455 {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
456 int i;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
457 FlacFrame *frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
458 FlacSubframe *sub;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
459
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
460 frame = &ctx->frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
461 sub = &frame->subframes[ch];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
462
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
463 /* warm-up samples */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
464 for(i=0; i<sub->order; i++) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
465 put_sbits(&ctx->pb, sub->obits, sub->residual[i]);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
466 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
467
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
468 /* residual */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
469 output_residual(ctx, ch);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
470 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
471
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
472 static void output_subframes(FlacEncodeContext *s)
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
473 {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
474 FlacFrame *frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
475 FlacSubframe *sub;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
476 int ch;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
477
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
478 frame = &s->frame;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
479
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
480 for(ch=0; ch<s->channels; ch++) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
481 sub = &frame->subframes[ch];
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
482
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
483 /* subframe header */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
484 put_bits(&s->pb, 1, 0);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
485 put_bits(&s->pb, 6, sub->type_code);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
486 put_bits(&s->pb, 1, 0); /* no wasted bits */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
487
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
488 /* subframe */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
489 if(sub->type == FLAC_SUBFRAME_VERBATIM) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
490 output_subframe_verbatim(s, ch);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
491 } else {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
492 output_subframe_fixed(s, ch);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
493 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
494 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
495 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
496
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
497 static void output_frame_footer(FlacEncodeContext *s)
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
498 {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
499 int crc;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
500 flush_put_bits(&s->pb);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
501 crc = bswap_16(av_crc(av_crc8005, 0, s->pb.buf, put_bits_count(&s->pb)>>3));
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
502 put_bits(&s->pb, 16, crc);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
503 flush_put_bits(&s->pb);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
504 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
505
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
506 static int flac_encode_frame(AVCodecContext *avctx, uint8_t *frame,
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
507 int buf_size, void *data)
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
508 {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
509 int ch;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
510 FlacEncodeContext *s;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
511 int16_t *samples = data;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
512 int out_bytes;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
513
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
514 s = avctx->priv_data;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
515
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
516 s->blocksize = avctx->frame_size;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
517 if(init_frame(s)) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
518 return 0;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
519 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
520
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
521 copy_samples(s, samples);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
522
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
523 for(ch=0; ch<s->channels; ch++) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
524 encode_residual(s, ch);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
525 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
526 init_put_bits(&s->pb, frame, buf_size);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
527 output_frame_header(s);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
528 output_subframes(s);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
529 output_frame_footer(s);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
530 out_bytes = put_bits_count(&s->pb) >> 3;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
531
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
532 if(out_bytes > s->max_framesize || out_bytes >= buf_size) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
533 /* frame too large. use verbatim mode */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
534 for(ch=0; ch<s->channels; ch++) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
535 encode_residual_verbatim(s, ch);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
536 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
537 init_put_bits(&s->pb, frame, buf_size);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
538 output_frame_header(s);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
539 output_subframes(s);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
540 output_frame_footer(s);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
541 out_bytes = put_bits_count(&s->pb) >> 3;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
542
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
543 if(out_bytes > s->max_framesize || out_bytes >= buf_size) {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
544 /* still too large. must be an error. */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
545 av_log(avctx, AV_LOG_ERROR, "error encoding frame\n");
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
546 return -1;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
547 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
548 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
549
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
550 s->frame_count++;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
551 return out_bytes;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
552 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
553
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
554 static int flac_encode_close(AVCodecContext *avctx)
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
555 {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
556 av_freep(&avctx->coded_frame);
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
557 return 0;
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
558 }
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
559
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
560 AVCodec flac_encoder = {
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
561 "flac",
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
562 CODEC_TYPE_AUDIO,
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
563 CODEC_ID_FLAC,
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
564 sizeof(FlacEncodeContext),
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
565 flac_encode_init,
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
566 flac_encode_frame,
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
567 flac_encode_close,
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
568 NULL,
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
569 .capabilities = CODEC_CAP_SMALL_LAST_FRAME,
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
570 };