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