annotate libaf/af_lavcac3enc.c @ 30903:565f6d0f0d2a

Make all instances of codec_patch unconditional, otherwise compilation will break on systems that do not have win32 dlls enabled. Fixes compilation bug introduced by r30942 10l to the anonymous guy who explains the importance of commit messages and would like to have romance novels in these very messages.
author attila
date Sun, 21 Mar 2010 10:13:00 +0000
parents 05f085c36d5b
children 1ba5eef167aa
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 *
26740
b3a38b361fef Use standard license headers with standard formatting.
diego
parents: 26120
diff changeset
18 * You should have received a copy of the GNU General Public License along
b3a38b361fef Use standard license headers with standard formatting.
diego
parents: 26120
diff changeset
19 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
b3a38b361fef Use standard license headers with standard formatting.
diego
parents: 26120
diff changeset
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25357
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
26120
24ba95d88181 Add directory names to libavcodec #includes.
diego
parents: 25962
diff changeset
33 #include "libavcodec/avcodec.h"
24ba95d88181 Add directory names to libavcodec #includes.
diego
parents: 25962
diff changeset
34 #include "libavcodec/ac3.h"
30243
05f085c36d5b Let the format filter do the AC3 endianness conversion instead of duplicating
reimar
parents: 30241
diff changeset
35 #include "libavutil/intreadwrite.h"
25357
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
36
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
37 // 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
38 typedef struct af_ac3enc_s {
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
39 struct AVCodec *lavc_acodec;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
40 struct AVCodecContext *lavc_actx;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
41 int add_iec61937_header;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
42 int bit_rate;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
43 char *pending_data;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
44 int pending_len;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
45 int expect_len;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
46 int min_channel_num;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
47 } af_ac3enc_t;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
48
25962
afa125da85cf typo fix: inited --> initialized
diego
parents: 25642
diff changeset
49 extern int avcodec_initialized;
25357
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
50
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
51 // Initialization and runtime control
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
52 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
53 {
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
54 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
55 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
56 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
57 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
58 {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
59
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
60 switch (cmd){
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
61 case AF_CONTROL_REINIT:
30241
02b9c1a452e1 Add support for distinguishing between little- and big-endian SPDIF AC3
reimar
parents: 29491
diff changeset
62 if (AF_FORMAT_IS_AC3(data->format) || data->nch < s->min_channel_num)
25357
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
63 return AF_DETACH;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
64
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
65 s->pending_len = 0;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
66 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
67 if (s->add_iec61937_header)
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
68 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
69 else
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
70 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
71
29049
8c706ce21c6f Remove af_msg special-casing API in libaf.
bircoph
parents: 26740
diff changeset
72 mp_msg(MSGT_AFILTER, MSGL_DBG2, "af_lavcac3enc reinit: %d, %d, %f, %d.\n",
25357
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
73 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
74
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
75 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
76 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
77 af->data->rate = data->rate;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
78 else
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
79 af->data->rate = 48000;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
80 if (data->nch > AC3_MAX_CHANNELS)
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
81 af->data->nch = AC3_MAX_CHANNELS;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
82 else
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
83 af->data->nch = data->nch;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
84 af->data->bps = 2;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
85 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
86
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
87 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
88
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
89 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
90 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
91 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
92
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
93 if (s->lavc_actx->codec)
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
94 avcodec_close(s->lavc_actx);
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
95
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
96 // Put sample parameters
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
97 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
98 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
99 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
100
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
101 if(avcodec_open(s->lavc_actx, s->lavc_acodec) < 0) {
29049
8c706ce21c6f Remove af_msg special-casing API in libaf.
bircoph
parents: 26740
diff changeset
102 mp_msg(MSGT_AFILTER, MSGL_ERR, MSGTR_CouldntOpenCodec, "ac3", bit_rate);
25357
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
103 return AF_ERROR;
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 }
30243
05f085c36d5b Let the format filter do the AC3 endianness conversion instead of duplicating
reimar
parents: 30241
diff changeset
106 af->data->format = AF_FORMAT_AC3_BE;
25357
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
107 af->data->nch = 2;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
108 return test_output_res;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
109 case AF_CONTROL_COMMAND_LINE:
29049
8c706ce21c6f Remove af_msg special-casing API in libaf.
bircoph
parents: 26740
diff changeset
110 mp_msg(MSGT_AFILTER, MSGL_DBG2, "af_lavcac3enc cmdline: %s.\n", (char*)arg);
25357
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
111 s->bit_rate = 0;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
112 s->min_channel_num = 0;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
113 s->add_iec61937_header = 0;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
114 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
115 &s->min_channel_num);
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
116 if (s->bit_rate < 1000)
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
117 s->bit_rate *= 1000;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
118 if (s->bit_rate) {
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
119 for (i = 0; i < 19; ++i)
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
120 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
121 break;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
122 if (i >= 19) {
29049
8c706ce21c6f Remove af_msg special-casing API in libaf.
bircoph
parents: 26740
diff changeset
123 mp_msg(MSGT_AFILTER, MSGL_WARN, "af_lavcac3enc unable set unsupported "
25357
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
124 "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
125 "supported bitrates).\n", s->bit_rate);
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
126 s->bit_rate = 0;
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 }
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
129 if (s->min_channel_num == 0)
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
130 s->min_channel_num = 5;
29049
8c706ce21c6f Remove af_msg special-casing API in libaf.
bircoph
parents: 26740
diff changeset
131 mp_msg(MSGT_AFILTER, MSGL_V, "af_lavcac3enc config spdif:%d, bitrate:%d, "
25357
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
132 "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
133 s->min_channel_num);
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
134 return AF_OK;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
135 }
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
136 return AF_UNKNOWN;
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
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
139 // Deallocate memory
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
140 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
141 {
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
142 if (af->data)
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
143 free(af->data->audio);
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
144 free(af->data);
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
145 if (af->setup) {
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
146 af_ac3enc_t *s = af->setup;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
147 af->setup = NULL;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
148 if(s->lavc_actx) {
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
149 if (s->lavc_actx->codec)
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
150 avcodec_close(s->lavc_actx);
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
151 free(s->lavc_actx);
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
152 }
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
153 free(s->pending_data);
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
154 free(s);
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
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
158 // Filter data through filter
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
159 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
160 {
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
161 af_ac3enc_t *s = af->setup;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
162 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
163 af_data_t *l;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
164 int len, left, outsize = 0, destsize;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
165 char *buf, *src, *dest;
25642
0c10c8859be8 Fix buffer overflow bug by calculate the buffer size accurately.
ulion
parents: 25357
diff changeset
166 int max_output_len;
0c10c8859be8 Fix buffer overflow bug by calculate the buffer size accurately.
ulion
parents: 25357
diff changeset
167 int frame_num = (data->len + s->pending_len) / s->expect_len;
25357
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
168
25642
0c10c8859be8 Fix buffer overflow bug by calculate the buffer size accurately.
ulion
parents: 25357
diff changeset
169 if (s->add_iec61937_header)
0c10c8859be8 Fix buffer overflow bug by calculate the buffer size accurately.
ulion
parents: 25357
diff changeset
170 max_output_len = AC3_FRAME_SIZE * 2 * 2 * frame_num;
0c10c8859be8 Fix buffer overflow bug by calculate the buffer size accurately.
ulion
parents: 25357
diff changeset
171 else
0c10c8859be8 Fix buffer overflow bug by calculate the buffer size accurately.
ulion
parents: 25357
diff changeset
172 max_output_len = AC3_MAX_CODED_FRAME_SIZE * frame_num;
0c10c8859be8 Fix buffer overflow bug by calculate the buffer size accurately.
ulion
parents: 25357
diff changeset
173
0c10c8859be8 Fix buffer overflow bug by calculate the buffer size accurately.
ulion
parents: 25357
diff changeset
174 if (af->data->len < max_output_len) {
29049
8c706ce21c6f Remove af_msg special-casing API in libaf.
bircoph
parents: 26740
diff changeset
175 mp_msg(MSGT_AFILTER, MSGL_V, "[libaf] Reallocating memory in module %s, "
25642
0c10c8859be8 Fix buffer overflow bug by calculate the buffer size accurately.
ulion
parents: 25357
diff changeset
176 "old len = %i, new len = %i\n", af->info->name, af->data->len,
0c10c8859be8 Fix buffer overflow bug by calculate the buffer size accurately.
ulion
parents: 25357
diff changeset
177 max_output_len);
0c10c8859be8 Fix buffer overflow bug by calculate the buffer size accurately.
ulion
parents: 25357
diff changeset
178 free(af->data->audio);
0c10c8859be8 Fix buffer overflow bug by calculate the buffer size accurately.
ulion
parents: 25357
diff changeset
179 af->data->audio = malloc(max_output_len);
0c10c8859be8 Fix buffer overflow bug by calculate the buffer size accurately.
ulion
parents: 25357
diff changeset
180 if (!af->data->audio) {
29049
8c706ce21c6f Remove af_msg special-casing API in libaf.
bircoph
parents: 26740
diff changeset
181 mp_msg(MSGT_AFILTER, MSGL_FATAL, "[libaf] Could not allocate memory \n");
25642
0c10c8859be8 Fix buffer overflow bug by calculate the buffer size accurately.
ulion
parents: 25357
diff changeset
182 return NULL;
0c10c8859be8 Fix buffer overflow bug by calculate the buffer size accurately.
ulion
parents: 25357
diff changeset
183 }
0c10c8859be8 Fix buffer overflow bug by calculate the buffer size accurately.
ulion
parents: 25357
diff changeset
184 af->data->len = max_output_len;
0c10c8859be8 Fix buffer overflow bug by calculate the buffer size accurately.
ulion
parents: 25357
diff changeset
185 }
25357
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 l = af->data; // Local data
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
188 buf = (char *)l->audio;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
189 src = (char *)c->audio;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
190 left = c->len;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
191
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
192
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
193 while (left > 0) {
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
194 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
195 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
196 src += left;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
197 s->pending_len += left;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
198 left = 0;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
199 break;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
200 }
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 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
203 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
204
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
205 if (s->pending_len) {
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
206 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
207 if (needs > 0) {
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
208 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
209 src += needs;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
210 left -= needs;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
211 }
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
212
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
213 if (c->nch >= 5)
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
214 reorder_channel_nch(s->pending_data,
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
215 AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT,
29491
99eda963d27a Fix incorrect channel ordering for lavc audio codecs (specifically ffac3,
tack
parents: 29401
diff changeset
216 AF_CHANNEL_LAYOUT_LAVC_DEFAULT,
25357
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
217 c->nch,
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
218 s->expect_len / 2, 2);
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 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
221 (void *)s->pending_data);
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
222 s->pending_len = 0;
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 else {
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
225 if (c->nch >= 5)
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
226 reorder_channel_nch(src,
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
227 AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT,
29491
99eda963d27a Fix incorrect channel ordering for lavc audio codecs (specifically ffac3,
tack
parents: 29401
diff changeset
228 AF_CHANNEL_LAYOUT_LAVC_DEFAULT,
25357
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
229 c->nch,
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
230 s->expect_len / 2, 2);
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
231 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
232 src += s->expect_len;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
233 left -= s->expect_len;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
234 }
29049
8c706ce21c6f Remove af_msg special-casing API in libaf.
bircoph
parents: 26740
diff changeset
235 mp_msg(MSGT_AFILTER, MSGL_DBG2, "avcodec_encode_audio got %d, pending %d.\n",
25357
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
236 len, s->pending_len);
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
237
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
238 if (s->add_iec61937_header) {
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
239 int bsmod = dest[5] & 0x7;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
240
30243
05f085c36d5b Let the format filter do the AC3 endianness conversion instead of duplicating
reimar
parents: 30241
diff changeset
241 AV_WB16(buf, 0xF872); // iec 61937 syncword 1
05f085c36d5b Let the format filter do the AC3 endianness conversion instead of duplicating
reimar
parents: 30241
diff changeset
242 AV_WB16(buf + 2, 0x4E1F); // iec 61937 syncword 2
05f085c36d5b Let the format filter do the AC3 endianness conversion instead of duplicating
reimar
parents: 30241
diff changeset
243 buf[4] = bsmod; // bsmod
05f085c36d5b Let the format filter do the AC3 endianness conversion instead of duplicating
reimar
parents: 30241
diff changeset
244 buf[5] = 0x01; // data-type ac3
05f085c36d5b Let the format filter do the AC3 endianness conversion instead of duplicating
reimar
parents: 30241
diff changeset
245 AV_WB16(buf + 6, len << 3); // number of bits in payload
25357
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 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
248 len = AC3_FRAME_SIZE * 2 * 2;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
249 }
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 outsize += len;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
252 buf += len;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
253 }
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
254 c->audio = l->audio;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
255 c->nch = 2;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
256 c->bps = 2;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
257 c->len = outsize;
29049
8c706ce21c6f Remove af_msg special-casing API in libaf.
bircoph
parents: 26740
diff changeset
258 mp_msg(MSGT_AFILTER, MSGL_DBG2, "play return size %d, pending %d\n",
25357
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
259 outsize, s->pending_len);
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
260 return c;
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
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
263 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
264
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
265 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
266 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
267 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
268
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
269 af->control=control;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
270 af->uninit=uninit;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
271 af->play=play;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
272 af->mul=1;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
273 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
274 af->setup=s;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
275
25962
afa125da85cf typo fix: inited --> initialized
diego
parents: 25642
diff changeset
276 if (!avcodec_initialized){
25357
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
277 avcodec_init();
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
278 avcodec_register_all();
25962
afa125da85cf typo fix: inited --> initialized
diego
parents: 25642
diff changeset
279 avcodec_initialized=1;
25357
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
280 }
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
281
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
282 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
283 if (!s->lavc_acodec) {
29049
8c706ce21c6f Remove af_msg special-casing API in libaf.
bircoph
parents: 26740
diff changeset
284 mp_msg(MSGT_AFILTER, MSGL_ERR, MSGTR_LavcAudioCodecNotFound, "ac3");
25357
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
285 return AF_ERROR;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
286 }
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
287
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
288 s->lavc_actx = avcodec_alloc_context();
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
289 if (!s->lavc_actx) {
29049
8c706ce21c6f Remove af_msg special-casing API in libaf.
bircoph
parents: 26740
diff changeset
290 mp_msg(MSGT_AFILTER, MSGL_ERR, MSGTR_CouldntAllocateLavcContext);
25357
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
291 return AF_ERROR;
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 return AF_OK;
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
295 }
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
296
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
297 af_info_t af_info_lavcac3enc = {
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
298 "runtime encode to ac3 using libavcodec",
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
299 "lavcac3enc",
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
300 "Ulion",
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
301 "",
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
302 AF_FLAGS_REENTRANT,
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
303 af_open
b265c001e64a Add new audio filter for encoding multi-channel audio into ac3 at runtime.
ulion
parents:
diff changeset
304 };