comparison libaf/af_lavcac3enc.c @ 25357:b265c001e64a

Add new audio filter for encoding multi-channel audio into ac3 at runtime. And if set first parameter of this filter to 1, it will do ac3 passthrough like hwac3 did.
author ulion
date Thu, 13 Dec 2007 12:38:17 +0000
parents
children 0c10c8859be8
comparison
equal deleted inserted replaced
25356:a5c22f3e4673 25357:b265c001e64a
1 /*
2 * audio filter for runtime AC-3 encoding with libavcodec.
3 *
4 * Copyright (C) 2007 Ulion <ulion A gmail P com>
5 *
6 * This file is part of MPlayer.
7 *
8 * MPlayer is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * MPlayer is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with MPlayer; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <inttypes.h>
27
28 #include "config.h"
29 #include "af.h"
30 #include "help_mp.h"
31 #include "reorder_ch.h"
32
33 #include "avcodec.h"
34 #include "ac3.h"
35
36 // Data for specific instances of this filter
37 typedef struct af_ac3enc_s {
38 struct AVCodec *lavc_acodec;
39 struct AVCodecContext *lavc_actx;
40 int add_iec61937_header;
41 int bit_rate;
42 char *pending_data;
43 int pending_len;
44 int expect_len;
45 int min_channel_num;
46 } af_ac3enc_t;
47
48 extern int avcodec_inited;
49
50 // Initialization and runtime control
51 static int control(struct af_instance_s *af, int cmd, void *arg)
52 {
53 af_ac3enc_t *s = (af_ac3enc_t *)af->setup;
54 af_data_t *data = (af_data_t *)arg;
55 int i, bit_rate, test_output_res;
56 static const int default_bit_rate[AC3_MAX_CHANNELS+1] = \
57 {0, 96000, 192000, 256000, 384000, 448000, 448000};
58
59 switch (cmd){
60 case AF_CONTROL_REINIT:
61 if (data->format == AF_FORMAT_AC3 || data->nch < s->min_channel_num)
62 return AF_DETACH;
63
64 s->pending_len = 0;
65 s->expect_len = AC3_FRAME_SIZE * data->nch * data->bps;
66 if (s->add_iec61937_header)
67 af->mul = (double)AC3_FRAME_SIZE * 2 * 2 / s->expect_len;
68 else
69 af->mul = (double)AC3_MAX_CODED_FRAME_SIZE / s->expect_len;
70
71 af_msg(AF_MSG_DEBUG0, "af_lavcac3enc reinit: %d, %d, %f, %d.\n",
72 data->nch, data->rate, af->mul, s->expect_len);
73
74 af->data->format = AF_FORMAT_S16_NE;
75 if (data->rate == 48000 || data->rate == 44100 || data->rate == 32000)
76 af->data->rate = data->rate;
77 else
78 af->data->rate = 48000;
79 if (data->nch > AC3_MAX_CHANNELS)
80 af->data->nch = AC3_MAX_CHANNELS;
81 else
82 af->data->nch = data->nch;
83 af->data->bps = 2;
84 test_output_res = af_test_output(af, data);
85
86 bit_rate = s->bit_rate ? s->bit_rate : default_bit_rate[af->data->nch];
87
88 if (s->lavc_actx->channels != af->data->nch ||
89 s->lavc_actx->sample_rate != af->data->rate ||
90 s->lavc_actx->bit_rate != bit_rate) {
91
92 if (s->lavc_actx->codec)
93 avcodec_close(s->lavc_actx);
94
95 // Put sample parameters
96 s->lavc_actx->channels = af->data->nch;
97 s->lavc_actx->sample_rate = af->data->rate;
98 s->lavc_actx->bit_rate = bit_rate;
99
100 if(avcodec_open(s->lavc_actx, s->lavc_acodec) < 0) {
101 af_msg(AF_MSG_ERROR, MSGTR_CouldntOpenCodec, "ac3", bit_rate);
102 return AF_ERROR;
103 }
104 }
105 af->data->format = AF_FORMAT_AC3;
106 af->data->nch = 2;
107 return test_output_res;
108 case AF_CONTROL_COMMAND_LINE:
109 af_msg(AF_MSG_DEBUG0, "af_lavcac3enc cmdline: %s.\n", (char*)arg);
110 s->bit_rate = 0;
111 s->min_channel_num = 0;
112 s->add_iec61937_header = 0;
113 sscanf((char*)arg,"%d:%d:%d", &s->add_iec61937_header, &s->bit_rate,
114 &s->min_channel_num);
115 if (s->bit_rate < 1000)
116 s->bit_rate *= 1000;
117 if (s->bit_rate) {
118 for (i = 0; i < 19; ++i)
119 if (ff_ac3_bitrate_tab[i] * 1000 == s->bit_rate)
120 break;
121 if (i >= 19) {
122 af_msg(AF_MSG_WARN, "af_lavcac3enc unable set unsupported "
123 "bitrate %d, use default bitrate (check manpage to see "
124 "supported bitrates).\n", s->bit_rate);
125 s->bit_rate = 0;
126 }
127 }
128 if (s->min_channel_num == 0)
129 s->min_channel_num = 5;
130 af_msg(AF_MSG_VERBOSE, "af_lavcac3enc config spdif:%d, bitrate:%d, "
131 "minchnum:%d.\n", s->add_iec61937_header, s->bit_rate,
132 s->min_channel_num);
133 return AF_OK;
134 }
135 return AF_UNKNOWN;
136 }
137
138 // Deallocate memory
139 static void uninit(struct af_instance_s* af)
140 {
141 if (af->data)
142 free(af->data->audio);
143 free(af->data);
144 if (af->setup) {
145 af_ac3enc_t *s = af->setup;
146 af->setup = NULL;
147 if(s->lavc_actx) {
148 if (s->lavc_actx->codec)
149 avcodec_close(s->lavc_actx);
150 free(s->lavc_actx);
151 }
152 free(s->pending_data);
153 free(s);
154 }
155 }
156
157 // Filter data through filter
158 static af_data_t* play(struct af_instance_s* af, af_data_t* data)
159 {
160 af_ac3enc_t *s = af->setup;
161 af_data_t *c = data; // Current working data
162 af_data_t *l;
163 int len, left, outsize = 0, destsize;
164 char *buf, *src, *dest;
165
166 if (AF_OK != RESIZE_LOCAL_BUFFER(af,data))
167 return NULL;
168
169 l = af->data; // Local data
170 buf = (char *)l->audio;
171 src = (char *)c->audio;
172 left = c->len;
173
174
175 while (left > 0) {
176 if (left + s->pending_len < s->expect_len) {
177 memcpy(s->pending_data + s->pending_len, src, left);
178 src += left;
179 s->pending_len += left;
180 left = 0;
181 break;
182 }
183
184 dest = s->add_iec61937_header ? buf + 8 : buf;
185 destsize = (char *)l->audio + l->len - buf;
186
187 if (s->pending_len) {
188 int needs = s->expect_len - s->pending_len;
189 if (needs > 0) {
190 memcpy(s->pending_data + s->pending_len, src, needs);
191 src += needs;
192 left -= needs;
193 }
194
195 if (c->nch >= 5)
196 reorder_channel_nch(s->pending_data,
197 AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT,
198 AF_CHANNEL_LAYOUT_LAVC_AC3_DEFAULT,
199 c->nch,
200 s->expect_len / 2, 2);
201
202 len = avcodec_encode_audio(s->lavc_actx, dest, destsize,
203 (void *)s->pending_data);
204 s->pending_len = 0;
205 }
206 else {
207 if (c->nch >= 5)
208 reorder_channel_nch(src,
209 AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT,
210 AF_CHANNEL_LAYOUT_LAVC_AC3_DEFAULT,
211 c->nch,
212 s->expect_len / 2, 2);
213 len = avcodec_encode_audio(s->lavc_actx,dest,destsize,(void *)src);
214 src += s->expect_len;
215 left -= s->expect_len;
216 }
217 af_msg(AF_MSG_DEBUG0, "avcodec_encode_audio got %d, pending %d.\n",
218 len, s->pending_len);
219
220 if (s->add_iec61937_header) {
221 int16_t *out = (int16_t *)buf;
222 int bsmod = dest[5] & 0x7;
223
224 #ifndef WORDS_BIGENDIAN
225 int i;
226 char tmp;
227 for (i = 0; i < len; i += 2) {
228 tmp = dest[i];
229 dest[i] = dest[i+1];
230 dest[i+1] = tmp;
231 }
232 if (len & 1) {
233 dest[len] = dest[len-1];
234 dest[len-1] = 0;
235 len++;
236 }
237 #endif
238 out[0] = 0xF872; // iec 61937 syncword 1
239 out[1] = 0x4E1F; // iec 61937 syncword 2
240 out[2] = 0x0001; // data-type ac3
241 out[2] |= bsmod << 8; // bsmod
242 out[3] = len << 3; // number of bits in payload
243
244 memset(buf + 8 + len, 0, AC3_FRAME_SIZE * 2 * 2 - 8 - len);
245 len = AC3_FRAME_SIZE * 2 * 2;
246 }
247
248 outsize += len;
249 buf += len;
250 }
251 c->audio = l->audio;
252 c->nch = 2;
253 c->bps = 2;
254 c->len = outsize;
255 af_msg(AF_MSG_DEBUG0, "play return size %d, pending %d\n",
256 outsize, s->pending_len);
257 return c;
258 }
259
260 static int af_open(af_instance_t* af){
261
262 af_ac3enc_t *s = calloc(1,sizeof(af_ac3enc_t));
263 int pending_space = 2 * AC3_MAX_CHANNELS * AC3_FRAME_SIZE;
264 s->pending_data = calloc(pending_space, sizeof(char));
265
266 af->control=control;
267 af->uninit=uninit;
268 af->play=play;
269 af->mul=1;
270 af->data=calloc(1,sizeof(af_data_t));
271 af->setup=s;
272
273 if (!avcodec_inited){
274 avcodec_init();
275 avcodec_register_all();
276 avcodec_inited=1;
277 }
278
279 s->lavc_acodec = avcodec_find_encoder_by_name("ac3");
280 if (!s->lavc_acodec) {
281 af_msg(AF_MSG_ERROR, MSGTR_LavcAudioCodecNotFound, "ac3");
282 return AF_ERROR;
283 }
284
285 s->lavc_actx = avcodec_alloc_context();
286 if (!s->lavc_actx) {
287 af_msg(AF_MSG_ERROR, MSGTR_CouldntAllocateLavcContext);
288 return AF_ERROR;
289 }
290
291 return AF_OK;
292 }
293
294 af_info_t af_info_lavcac3enc = {
295 "runtime encode to ac3 using libavcodec",
296 "lavcac3enc",
297 "Ulion",
298 "",
299 AF_FLAGS_REENTRANT,
300 af_open
301 };