Mercurial > mplayer.hg
annotate libmpcodecs/ae_lavc.c @ 30088:4977e04f3a18
Add support for parsing audio streams (though should be easy to extend to video)
via libavcodec.
Parsing can be done at the demuxer stage (currently disabled) or at the decoder
(ad_ffmpeg, enabled).
Should allow using the libavcodec AAC, DTS, ... decoders independent of container
format.
author | reimar |
---|---|
date | Sun, 27 Dec 2009 15:28:01 +0000 |
parents | a3cc38ad5878 |
children | bbb6ebec87a0 |
rev | line source |
---|---|
15234 | 1 #include <stdio.h> |
2 #include <stdlib.h> | |
3 #include <inttypes.h> | |
15238 | 4 #include <unistd.h> |
15234 | 5 #include <string.h> |
15240 | 6 #include <sys/types.h> |
26203 | 7 #include "config.h" |
15234 | 8 #include "m_option.h" |
17012 | 9 #include "mp_msg.h" |
22601
ed8f90096c65
Add explicit location for headers from the libmpdemux/ directory.
diego
parents:
22600
diff
changeset
|
10 #include "libmpdemux/aviheader.h" |
ed8f90096c65
Add explicit location for headers from the libmpdemux/ directory.
diego
parents:
22600
diff
changeset
|
11 #include "libmpdemux/ms_hdr.h" |
22600
3c2b4a866c6a
Add explicit location for headers from the stream/ directory.
diego
parents:
22316
diff
changeset
|
12 #include "stream/stream.h" |
22601
ed8f90096c65
Add explicit location for headers from the libmpdemux/ directory.
diego
parents:
22600
diff
changeset
|
13 #include "libmpdemux/muxer.h" |
15234 | 14 #include "ae_lavc.h" |
15 #include "help_mp.h" | |
17012 | 16 #include "libaf/af_format.h" |
25315
dfa8a510c81c
Fix all current known multi-channel wrong order problems by adding
ulion
parents:
24359
diff
changeset
|
17 #include "libaf/reorder_ch.h" |
15234 | 18 #include "libavcodec/avcodec.h" |
28132 | 19 #include "libavutil/intreadwrite.h" |
15234 | 20 |
21 static AVCodec *lavc_acodec; | |
22 static AVCodecContext *lavc_actx; | |
23 extern char *lavc_param_acodec; | |
24 extern int lavc_param_abitrate; | |
25 extern int lavc_param_atag; | |
17842 | 26 extern int lavc_param_audio_global_header; |
25962 | 27 extern int avcodec_initialized; |
15234 | 28 static int compressed_frame_size = 0; |
27341
e7c989f7a7c9
Start unifying names of internal preprocessor directives.
diego
parents:
26203
diff
changeset
|
29 #ifdef CONFIG_LIBAVFORMAT |
21820
cd705f30bb31
Include libavformat/riff.h when building with static libavformat and
reimar
parents:
21773
diff
changeset
|
30 #include "libavformat/avformat.h" |
21966
d9494ca70ca7
Simplify by using av_codec_get_id and include riff.h only in demux_lavf.c
reimar
parents:
21963
diff
changeset
|
31 extern const struct AVCodecTag *mp_wav_taglists[]; |
17096 | 32 #endif |
15234 | 33 |
34 static int bind_lavc(audio_encoder_t *encoder, muxer_stream_t *mux_a) | |
35 { | |
36 mux_a->wf = malloc(sizeof(WAVEFORMATEX)+lavc_actx->extradata_size+256); | |
37 mux_a->wf->wFormatTag = lavc_param_atag; | |
38 mux_a->wf->nChannels = lavc_actx->channels; | |
39 mux_a->wf->nSamplesPerSec = lavc_actx->sample_rate; | |
40 mux_a->wf->nAvgBytesPerSec = (lavc_actx->bit_rate / 8); | |
19360
d4d72e5eea07
pass average bitrate from encoder to (lavf) muxer
michael
parents:
17855
diff
changeset
|
41 mux_a->avg_rate= lavc_actx->bit_rate; |
15234 | 42 mux_a->h.dwRate = mux_a->wf->nAvgBytesPerSec; |
43 if(lavc_actx->block_align) | |
44 mux_a->h.dwSampleSize = mux_a->h.dwScale = lavc_actx->block_align; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28928
diff
changeset
|
45 else |
15234 | 46 { |
47 mux_a->h.dwScale = (mux_a->wf->nAvgBytesPerSec * lavc_actx->frame_size)/ mux_a->wf->nSamplesPerSec; /* for cbr */ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28928
diff
changeset
|
48 |
15234 | 49 if ((mux_a->wf->nAvgBytesPerSec * |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28928
diff
changeset
|
50 lavc_actx->frame_size) % mux_a->wf->nSamplesPerSec) |
15234 | 51 { |
52 mux_a->h.dwScale = lavc_actx->frame_size; | |
53 mux_a->h.dwRate = lavc_actx->sample_rate; | |
54 mux_a->h.dwSampleSize = 0; // Blocksize not constant | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28928
diff
changeset
|
55 } |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28928
diff
changeset
|
56 else |
21773
03bc990498fc
the avi spec does not allow random samplesize whoever wrote this should be shot
michael
parents:
21771
diff
changeset
|
57 mux_a->h.dwSampleSize = 0; |
15234 | 58 } |
21773
03bc990498fc
the avi spec does not allow random samplesize whoever wrote this should be shot
michael
parents:
21771
diff
changeset
|
59 if(mux_a->h.dwSampleSize) |
03bc990498fc
the avi spec does not allow random samplesize whoever wrote this should be shot
michael
parents:
21771
diff
changeset
|
60 mux_a->wf->nBlockAlign = mux_a->h.dwSampleSize; |
03bc990498fc
the avi spec does not allow random samplesize whoever wrote this should be shot
michael
parents:
21771
diff
changeset
|
61 else |
03bc990498fc
the avi spec does not allow random samplesize whoever wrote this should be shot
michael
parents:
21771
diff
changeset
|
62 mux_a->wf->nBlockAlign = 1; |
15234 | 63 mux_a->h.dwSuggestedBufferSize = (encoder->params.audio_preload*mux_a->wf->nAvgBytesPerSec)/1000; |
64 mux_a->h.dwSuggestedBufferSize -= mux_a->h.dwSuggestedBufferSize % mux_a->wf->nBlockAlign; | |
65 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28928
diff
changeset
|
66 switch(lavc_param_atag) |
15234 | 67 { |
68 case 0x11: /* imaadpcm */ | |
69 mux_a->wf->wBitsPerSample = 4; | |
70 mux_a->wf->cbSize = 2; | |
28132 | 71 AV_WL16(mux_a->wf+1, lavc_actx->frame_size); |
15234 | 72 break; |
73 case 0x55: /* mp3 */ | |
74 mux_a->wf->cbSize = 12; | |
75 mux_a->wf->wBitsPerSample = 0; /* does not apply */ | |
76 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->wID = 1; | |
77 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->fdwFlags = 2; | |
78 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nBlockSize = mux_a->wf->nBlockAlign; | |
79 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nFramesPerBlock = 1; | |
80 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nCodecDelay = 0; | |
81 break; | |
82 default: | |
83 mux_a->wf->wBitsPerSample = 0; /* Unknown */ | |
84 if (lavc_actx->extradata && (lavc_actx->extradata_size > 0)) | |
85 { | |
15501
7cdc07507650
wrong memcpy of extradata; 10l to whomever wrote that broken code
nicodvb
parents:
15244
diff
changeset
|
86 memcpy(mux_a->wf+1, lavc_actx->extradata, lavc_actx->extradata_size); |
15234 | 87 mux_a->wf->cbSize = lavc_actx->extradata_size; |
88 } | |
89 else | |
90 mux_a->wf->cbSize = 0; | |
91 break; | |
92 } | |
93 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28928
diff
changeset
|
94 // Fix allocation |
15234 | 95 mux_a->wf = realloc(mux_a->wf, sizeof(WAVEFORMATEX)+mux_a->wf->cbSize); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28928
diff
changeset
|
96 |
15234 | 97 encoder->input_format = AF_FORMAT_S16_NE; |
98 encoder->min_buffer_size = mux_a->h.dwSuggestedBufferSize; | |
99 encoder->max_buffer_size = mux_a->h.dwSuggestedBufferSize*2; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28928
diff
changeset
|
100 |
15234 | 101 return 1; |
102 } | |
103 | |
104 static int encode_lavc(audio_encoder_t *encoder, uint8_t *dest, void *src, int size, int max_size) | |
105 { | |
106 int n; | |
25315
dfa8a510c81c
Fix all current known multi-channel wrong order problems by adding
ulion
parents:
24359
diff
changeset
|
107 if ((encoder->params.channels == 6 || encoder->params.channels == 5) && |
dfa8a510c81c
Fix all current known multi-channel wrong order problems by adding
ulion
parents:
24359
diff
changeset
|
108 (!strcmp(lavc_acodec->name,"ac3") || |
dfa8a510c81c
Fix all current known multi-channel wrong order problems by adding
ulion
parents:
24359
diff
changeset
|
109 !strcmp(lavc_acodec->name,"libfaac"))) { |
dfa8a510c81c
Fix all current known multi-channel wrong order problems by adding
ulion
parents:
24359
diff
changeset
|
110 int isac3 = !strcmp(lavc_acodec->name,"ac3"); |
dfa8a510c81c
Fix all current known multi-channel wrong order problems by adding
ulion
parents:
24359
diff
changeset
|
111 reorder_channel_nch(src, AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT, |
29491
99eda963d27a
Fix incorrect channel ordering for lavc audio codecs (specifically ffac3,
tack
parents:
29263
diff
changeset
|
112 isac3 ? AF_CHANNEL_LAYOUT_LAVC_DEFAULT |
25315
dfa8a510c81c
Fix all current known multi-channel wrong order problems by adding
ulion
parents:
24359
diff
changeset
|
113 : AF_CHANNEL_LAYOUT_AAC_DEFAULT, |
dfa8a510c81c
Fix all current known multi-channel wrong order problems by adding
ulion
parents:
24359
diff
changeset
|
114 encoder->params.channels, |
dfa8a510c81c
Fix all current known multi-channel wrong order problems by adding
ulion
parents:
24359
diff
changeset
|
115 size / 2, 2); |
dfa8a510c81c
Fix all current known multi-channel wrong order problems by adding
ulion
parents:
24359
diff
changeset
|
116 } |
15234 | 117 n = avcodec_encode_audio(lavc_actx, dest, size, src); |
17855
4b1930c9345c
do not randomly chop up packets, this isnt allowed in almost no container
michael
parents:
17842
diff
changeset
|
118 compressed_frame_size = n; |
15234 | 119 return n; |
120 } | |
121 | |
122 | |
123 static int close_lavc(audio_encoder_t *encoder) | |
124 { | |
125 compressed_frame_size = 0; | |
126 return 1; | |
127 } | |
128 | |
129 static int get_frame_size(audio_encoder_t *encoder) | |
130 { | |
17855
4b1930c9345c
do not randomly chop up packets, this isnt allowed in almost no container
michael
parents:
17842
diff
changeset
|
131 int sz = compressed_frame_size; |
4b1930c9345c
do not randomly chop up packets, this isnt allowed in almost no container
michael
parents:
17842
diff
changeset
|
132 compressed_frame_size = 0; |
4b1930c9345c
do not randomly chop up packets, this isnt allowed in almost no container
michael
parents:
17842
diff
changeset
|
133 return sz; |
15234 | 134 } |
135 | |
27341
e7c989f7a7c9
Start unifying names of internal preprocessor directives.
diego
parents:
26203
diff
changeset
|
136 #ifndef CONFIG_LIBAVFORMAT |
15244
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
137 static uint32_t lavc_find_atag(char *codec) |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
138 { |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
139 if(codec == NULL) |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
140 return 0; |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
141 |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
142 if(! strcasecmp(codec, "mp2")) |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
143 return 0x50; |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
144 |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
145 if(! strcasecmp(codec, "mp3")) |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
146 return 0x55; |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
147 |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
148 if(! strcasecmp(codec, "ac3")) |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
149 return 0x2000; |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
150 |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
151 if(! strcasecmp(codec, "adpcm_ima_wav")) |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
152 return 0x11; |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
153 |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
154 if(! strncasecmp(codec, "bonk", 4)) |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
155 return 0x2048; |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
156 |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
157 return 0; |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
158 } |
24359 | 159 #endif |
15244
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
160 |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
161 |
15234 | 162 int mpae_init_lavc(audio_encoder_t *encoder) |
163 { | |
164 encoder->params.samples_per_frame = encoder->params.sample_rate; | |
165 encoder->params.bitrate = encoder->params.sample_rate * encoder->params.channels * 2 * 8; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28928
diff
changeset
|
166 |
15234 | 167 if(!lavc_param_acodec) |
168 { | |
169 mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_NoLavcAudioCodecName); | |
170 return 0; | |
171 } | |
172 | |
25962 | 173 if(!avcodec_initialized){ |
15234 | 174 avcodec_init(); |
175 avcodec_register_all(); | |
25962 | 176 avcodec_initialized=1; |
15234 | 177 } |
178 | |
179 lavc_acodec = avcodec_find_encoder_by_name(lavc_param_acodec); | |
180 if (!lavc_acodec) | |
181 { | |
182 mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_LavcAudioCodecNotFound, lavc_param_acodec); | |
183 return 0; | |
184 } | |
185 if(lavc_param_atag == 0) | |
186 { | |
27341
e7c989f7a7c9
Start unifying names of internal preprocessor directives.
diego
parents:
26203
diff
changeset
|
187 #ifdef CONFIG_LIBAVFORMAT |
21966
d9494ca70ca7
Simplify by using av_codec_get_id and include riff.h only in demux_lavf.c
reimar
parents:
21963
diff
changeset
|
188 lavc_param_atag = av_codec_get_tag(mp_wav_taglists, lavc_acodec->id); |
15244
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
189 #else |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
190 lavc_param_atag = lavc_find_atag(lavc_param_acodec); |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
191 #endif |
15234 | 192 if(!lavc_param_atag) |
193 { | |
194 mp_msg(MSGT_MENCODER, MSGL_FATAL, "Couldn't find wav tag for specified codec, exit\n"); | |
195 return 0; | |
196 } | |
197 } | |
198 | |
199 lavc_actx = avcodec_alloc_context(); | |
200 if(lavc_actx == NULL) | |
201 { | |
202 mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_CouldntAllocateLavcContext); | |
203 return 0; | |
204 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28928
diff
changeset
|
205 |
29673
a3cc38ad5878
Set codec_type and codec_id in codec context for lavc encoders.
reimar
parents:
29491
diff
changeset
|
206 lavc_actx->codec_type = CODEC_TYPE_AUDIO; |
a3cc38ad5878
Set codec_type and codec_id in codec context for lavc encoders.
reimar
parents:
29491
diff
changeset
|
207 lavc_actx->codec_id = lavc_acodec->id; |
15234 | 208 // put sample parameters |
209 lavc_actx->channels = encoder->params.channels; | |
210 lavc_actx->sample_rate = encoder->params.sample_rate; | |
28660
0812215421d7
Set time_base to 1/samplerate, like FFmpeg does, instead of leaving it at the
diego
parents:
28132
diff
changeset
|
211 lavc_actx->time_base.num = 1; |
0812215421d7
Set time_base to 1/samplerate, like FFmpeg does, instead of leaving it at the
diego
parents:
28132
diff
changeset
|
212 lavc_actx->time_base.den = encoder->params.sample_rate; |
23957
74eb6825d332
allow to specify the audio bitrate in bits (some codecs need that ...)
michael
parents:
23121
diff
changeset
|
213 if(lavc_param_abitrate<1000) |
74eb6825d332
allow to specify the audio bitrate in bits (some codecs need that ...)
michael
parents:
23121
diff
changeset
|
214 lavc_actx->bit_rate = encoder->params.bitrate = lavc_param_abitrate * 1000; |
74eb6825d332
allow to specify the audio bitrate in bits (some codecs need that ...)
michael
parents:
23121
diff
changeset
|
215 else |
74eb6825d332
allow to specify the audio bitrate in bits (some codecs need that ...)
michael
parents:
23121
diff
changeset
|
216 lavc_actx->bit_rate = encoder->params.bitrate = lavc_param_abitrate; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28928
diff
changeset
|
217 |
15234 | 218 |
219 /* | |
220 * Special case for adpcm_ima_wav. | |
22316
f3d7a1b58a82
cosmetics: Fix some common typos, appropiate --> appropRiate,
diego
parents:
21966
diff
changeset
|
221 * The bitrate is only dependent on samplerate. |
15234 | 222 * We have to known frame_size and block_align in advance, |
223 * so I just copied the code from libavcodec/adpcm.c | |
224 * | |
225 * However, ms adpcm_ima_wav uses a block_align of 2048, | |
226 * lavc defaults to 1024 | |
227 */ | |
228 if(lavc_param_atag == 0x11) { | |
229 int blkalign = 2048; | |
230 int framesize = (blkalign - 4 * lavc_actx->channels) * 8 / (4 * lavc_actx->channels) + 1; | |
231 lavc_actx->bit_rate = lavc_actx->sample_rate*8*blkalign/framesize; | |
232 } | |
17842 | 233 if((lavc_param_audio_global_header&1) |
234 /*|| (video_global_header==0 && (oc->oformat->flags & AVFMT_GLOBALHEADER))*/){ | |
235 lavc_actx->flags |= CODEC_FLAG_GLOBAL_HEADER; | |
236 } | |
237 if(lavc_param_audio_global_header&2){ | |
238 lavc_actx->flags2 |= CODEC_FLAG2_LOCAL_HEADER; | |
239 } | |
15234 | 240 |
241 if(avcodec_open(lavc_actx, lavc_acodec) < 0) | |
242 { | |
243 mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_CouldntOpenCodec, lavc_param_acodec, lavc_param_abitrate); | |
244 return 0; | |
245 } | |
246 | |
247 if(lavc_param_atag == 0x11) { | |
248 lavc_actx->block_align = 2048; | |
249 lavc_actx->frame_size = (lavc_actx->block_align - 4 * lavc_actx->channels) * 8 / (4 * lavc_actx->channels) + 1; | |
250 } | |
251 | |
252 encoder->decode_buffer_size = lavc_actx->frame_size * 2 * encoder->params.channels; | |
28928
f2b3f28982b8
Avoid ridiculously small decode_buffer_size (e.g. 4 with acodec=pcm_s16le)
reimar
parents:
28660
diff
changeset
|
253 while (encoder->decode_buffer_size < 1024) encoder->decode_buffer_size *= 2; |
15234 | 254 encoder->bind = bind_lavc; |
255 encoder->get_frame_size = get_frame_size; | |
256 encoder->encode = encode_lavc; | |
257 encoder->close = close_lavc; | |
258 | |
259 return 1; | |
260 } | |
261 |