Mercurial > mplayer.hg
annotate libmpcodecs/ae_lavc.c @ 25376:382aeacc771f
The buffer used for pread need be aligned, but currently it got an offset 23
to the structure head. This will cause the pread always got random data
on some machines (such as my iMac G5 PPC with 10.5 os) so can not play vcd.
I also tried use DKIOCCDREAD ioctl call, but the result is same -- buffer need
be aligned. It could be a bug of os x or its dev lib.
Now fix this problem by move the buffer to a good aligned position in structure.
author | ulion |
---|---|
date | Sat, 15 Dec 2007 12:17:51 +0000 |
parents | dfa8a510c81c |
children | afa125da85cf |
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> |
15234 | 7 #include "m_option.h" |
17012 | 8 #include "mp_msg.h" |
22601
ed8f90096c65
Add explicit location for headers from the libmpdemux/ directory.
diego
parents:
22600
diff
changeset
|
9 #include "libmpdemux/aviheader.h" |
ed8f90096c65
Add explicit location for headers from the libmpdemux/ directory.
diego
parents:
22600
diff
changeset
|
10 #include "libmpdemux/ms_hdr.h" |
22600
3c2b4a866c6a
Add explicit location for headers from the stream/ directory.
diego
parents:
22316
diff
changeset
|
11 #include "stream/stream.h" |
22601
ed8f90096c65
Add explicit location for headers from the libmpdemux/ directory.
diego
parents:
22600
diff
changeset
|
12 #include "libmpdemux/muxer.h" |
15234 | 13 #include "ae_lavc.h" |
14 #include "help_mp.h" | |
17012 | 15 #include "config.h" |
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 #ifdef USE_LIBAVCODEC_SO |
19 #include <ffmpeg/avcodec.h> | |
20 #else | |
21 #include "libavcodec/avcodec.h" | |
22 #endif | |
23 | |
24 static AVCodec *lavc_acodec; | |
25 static AVCodecContext *lavc_actx; | |
26 extern char *lavc_param_acodec; | |
27 extern int lavc_param_abitrate; | |
28 extern int lavc_param_atag; | |
17842 | 29 extern int lavc_param_audio_global_header; |
15234 | 30 extern int avcodec_inited; |
31 static int compressed_frame_size = 0; | |
23121
a257dd426da5
Simplify preprocessor directives: There is a general variable for
diego
parents:
22601
diff
changeset
|
32 #ifdef USE_LIBAVFORMAT |
21820
cd705f30bb31
Include libavformat/riff.h when building with static libavformat and
reimar
parents:
21773
diff
changeset
|
33 #ifdef USE_LIBAVFORMAT_SO |
cd705f30bb31
Include libavformat/riff.h when building with static libavformat and
reimar
parents:
21773
diff
changeset
|
34 #include <ffmpeg/avformat.h> |
cd705f30bb31
Include libavformat/riff.h when building with static libavformat and
reimar
parents:
21773
diff
changeset
|
35 #else |
cd705f30bb31
Include libavformat/riff.h when building with static libavformat and
reimar
parents:
21773
diff
changeset
|
36 #include "libavformat/avformat.h" |
21822
fc4ce8a91a2e
Include "internal" libavformat/riff.h also when dynamic libavformat is used
reimar
parents:
21820
diff
changeset
|
37 #endif |
21966
d9494ca70ca7
Simplify by using av_codec_get_id and include riff.h only in demux_lavf.c
reimar
parents:
21963
diff
changeset
|
38 extern const struct AVCodecTag *mp_wav_taglists[]; |
17096 | 39 #endif |
15234 | 40 |
41 static int bind_lavc(audio_encoder_t *encoder, muxer_stream_t *mux_a) | |
42 { | |
43 mux_a->wf = malloc(sizeof(WAVEFORMATEX)+lavc_actx->extradata_size+256); | |
44 mux_a->wf->wFormatTag = lavc_param_atag; | |
45 mux_a->wf->nChannels = lavc_actx->channels; | |
46 mux_a->wf->nSamplesPerSec = lavc_actx->sample_rate; | |
47 mux_a->wf->nAvgBytesPerSec = (lavc_actx->bit_rate / 8); | |
19360
d4d72e5eea07
pass average bitrate from encoder to (lavf) muxer
michael
parents:
17855
diff
changeset
|
48 mux_a->avg_rate= lavc_actx->bit_rate; |
15234 | 49 mux_a->h.dwRate = mux_a->wf->nAvgBytesPerSec; |
50 if(lavc_actx->block_align) | |
51 mux_a->h.dwSampleSize = mux_a->h.dwScale = lavc_actx->block_align; | |
52 else | |
53 { | |
54 mux_a->h.dwScale = (mux_a->wf->nAvgBytesPerSec * lavc_actx->frame_size)/ mux_a->wf->nSamplesPerSec; /* for cbr */ | |
55 | |
56 if ((mux_a->wf->nAvgBytesPerSec * | |
57 lavc_actx->frame_size) % mux_a->wf->nSamplesPerSec) | |
58 { | |
59 mux_a->h.dwScale = lavc_actx->frame_size; | |
60 mux_a->h.dwRate = lavc_actx->sample_rate; | |
61 mux_a->h.dwSampleSize = 0; // Blocksize not constant | |
62 } | |
63 else | |
21773
03bc990498fc
the avi spec does not allow random samplesize whoever wrote this should be shot
michael
parents:
21771
diff
changeset
|
64 mux_a->h.dwSampleSize = 0; |
15234 | 65 } |
21773
03bc990498fc
the avi spec does not allow random samplesize whoever wrote this should be shot
michael
parents:
21771
diff
changeset
|
66 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
|
67 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
|
68 else |
03bc990498fc
the avi spec does not allow random samplesize whoever wrote this should be shot
michael
parents:
21771
diff
changeset
|
69 mux_a->wf->nBlockAlign = 1; |
15234 | 70 mux_a->h.dwSuggestedBufferSize = (encoder->params.audio_preload*mux_a->wf->nAvgBytesPerSec)/1000; |
71 mux_a->h.dwSuggestedBufferSize -= mux_a->h.dwSuggestedBufferSize % mux_a->wf->nBlockAlign; | |
72 | |
73 switch(lavc_param_atag) | |
74 { | |
75 case 0x11: /* imaadpcm */ | |
76 mux_a->wf->wBitsPerSample = 4; | |
77 mux_a->wf->cbSize = 2; | |
78 ((uint16_t*)mux_a->wf)[sizeof(WAVEFORMATEX)] = | |
79 ((lavc_actx->block_align - 4 * lavc_actx->channels) / (4 * lavc_actx->channels)) * 8 + 1; | |
80 break; | |
81 case 0x55: /* mp3 */ | |
82 mux_a->wf->cbSize = 12; | |
83 mux_a->wf->wBitsPerSample = 0; /* does not apply */ | |
84 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->wID = 1; | |
85 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->fdwFlags = 2; | |
86 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nBlockSize = mux_a->wf->nBlockAlign; | |
87 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nFramesPerBlock = 1; | |
88 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nCodecDelay = 0; | |
89 break; | |
90 default: | |
91 mux_a->wf->wBitsPerSample = 0; /* Unknown */ | |
92 if (lavc_actx->extradata && (lavc_actx->extradata_size > 0)) | |
93 { | |
15501
7cdc07507650
wrong memcpy of extradata; 10l to whomever wrote that broken code
nicodvb
parents:
15244
diff
changeset
|
94 memcpy(mux_a->wf+1, lavc_actx->extradata, lavc_actx->extradata_size); |
15234 | 95 mux_a->wf->cbSize = lavc_actx->extradata_size; |
96 } | |
97 else | |
98 mux_a->wf->cbSize = 0; | |
99 break; | |
100 } | |
101 | |
102 // Fix allocation | |
103 mux_a->wf = realloc(mux_a->wf, sizeof(WAVEFORMATEX)+mux_a->wf->cbSize); | |
104 | |
105 encoder->input_format = AF_FORMAT_S16_NE; | |
106 encoder->min_buffer_size = mux_a->h.dwSuggestedBufferSize; | |
107 encoder->max_buffer_size = mux_a->h.dwSuggestedBufferSize*2; | |
108 | |
109 return 1; | |
110 } | |
111 | |
112 static int encode_lavc(audio_encoder_t *encoder, uint8_t *dest, void *src, int size, int max_size) | |
113 { | |
114 int n; | |
25315
dfa8a510c81c
Fix all current known multi-channel wrong order problems by adding
ulion
parents:
24359
diff
changeset
|
115 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
|
116 (!strcmp(lavc_acodec->name,"ac3") || |
dfa8a510c81c
Fix all current known multi-channel wrong order problems by adding
ulion
parents:
24359
diff
changeset
|
117 !strcmp(lavc_acodec->name,"libfaac"))) { |
dfa8a510c81c
Fix all current known multi-channel wrong order problems by adding
ulion
parents:
24359
diff
changeset
|
118 int isac3 = !strcmp(lavc_acodec->name,"ac3"); |
dfa8a510c81c
Fix all current known multi-channel wrong order problems by adding
ulion
parents:
24359
diff
changeset
|
119 reorder_channel_nch(src, AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT, |
dfa8a510c81c
Fix all current known multi-channel wrong order problems by adding
ulion
parents:
24359
diff
changeset
|
120 isac3 ? AF_CHANNEL_LAYOUT_LAVC_AC3_DEFAULT |
dfa8a510c81c
Fix all current known multi-channel wrong order problems by adding
ulion
parents:
24359
diff
changeset
|
121 : AF_CHANNEL_LAYOUT_AAC_DEFAULT, |
dfa8a510c81c
Fix all current known multi-channel wrong order problems by adding
ulion
parents:
24359
diff
changeset
|
122 encoder->params.channels, |
dfa8a510c81c
Fix all current known multi-channel wrong order problems by adding
ulion
parents:
24359
diff
changeset
|
123 size / 2, 2); |
dfa8a510c81c
Fix all current known multi-channel wrong order problems by adding
ulion
parents:
24359
diff
changeset
|
124 } |
15234 | 125 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
|
126 compressed_frame_size = n; |
15234 | 127 return n; |
128 } | |
129 | |
130 | |
131 static int close_lavc(audio_encoder_t *encoder) | |
132 { | |
133 compressed_frame_size = 0; | |
134 return 1; | |
135 } | |
136 | |
137 static int get_frame_size(audio_encoder_t *encoder) | |
138 { | |
17855
4b1930c9345c
do not randomly chop up packets, this isnt allowed in almost no container
michael
parents:
17842
diff
changeset
|
139 int sz = compressed_frame_size; |
4b1930c9345c
do not randomly chop up packets, this isnt allowed in almost no container
michael
parents:
17842
diff
changeset
|
140 compressed_frame_size = 0; |
4b1930c9345c
do not randomly chop up packets, this isnt allowed in almost no container
michael
parents:
17842
diff
changeset
|
141 return sz; |
15234 | 142 } |
143 | |
24359 | 144 #ifndef USE_LIBAVFORMAT |
15244
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
145 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
|
146 { |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
147 if(codec == NULL) |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
148 return 0; |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
149 |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
150 if(! strcasecmp(codec, "mp2")) |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
151 return 0x50; |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
152 |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
153 if(! strcasecmp(codec, "mp3")) |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
154 return 0x55; |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
155 |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
156 if(! strcasecmp(codec, "ac3")) |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
157 return 0x2000; |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
158 |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
159 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
|
160 return 0x11; |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
161 |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
162 if(! strncasecmp(codec, "bonk", 4)) |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
163 return 0x2048; |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
164 |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
165 return 0; |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
166 } |
24359 | 167 #endif |
15244
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
168 |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
169 |
15234 | 170 int mpae_init_lavc(audio_encoder_t *encoder) |
171 { | |
172 encoder->params.samples_per_frame = encoder->params.sample_rate; | |
173 encoder->params.bitrate = encoder->params.sample_rate * encoder->params.channels * 2 * 8; | |
174 | |
175 if(!lavc_param_acodec) | |
176 { | |
177 mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_NoLavcAudioCodecName); | |
178 return 0; | |
179 } | |
180 | |
181 if(!avcodec_inited){ | |
182 avcodec_init(); | |
183 avcodec_register_all(); | |
184 avcodec_inited=1; | |
185 } | |
186 | |
187 lavc_acodec = avcodec_find_encoder_by_name(lavc_param_acodec); | |
188 if (!lavc_acodec) | |
189 { | |
190 mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_LavcAudioCodecNotFound, lavc_param_acodec); | |
191 return 0; | |
192 } | |
193 if(lavc_param_atag == 0) | |
194 { | |
23121
a257dd426da5
Simplify preprocessor directives: There is a general variable for
diego
parents:
22601
diff
changeset
|
195 #ifdef USE_LIBAVFORMAT |
21966
d9494ca70ca7
Simplify by using av_codec_get_id and include riff.h only in demux_lavf.c
reimar
parents:
21963
diff
changeset
|
196 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
|
197 #else |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
198 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
|
199 #endif |
15234 | 200 if(!lavc_param_atag) |
201 { | |
202 mp_msg(MSGT_MENCODER, MSGL_FATAL, "Couldn't find wav tag for specified codec, exit\n"); | |
203 return 0; | |
204 } | |
205 } | |
206 | |
207 lavc_actx = avcodec_alloc_context(); | |
208 if(lavc_actx == NULL) | |
209 { | |
210 mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_CouldntAllocateLavcContext); | |
211 return 0; | |
212 } | |
213 | |
214 // put sample parameters | |
215 lavc_actx->channels = encoder->params.channels; | |
216 lavc_actx->sample_rate = encoder->params.sample_rate; | |
23957
74eb6825d332
allow to specify the audio bitrate in bits (some codecs need that ...)
michael
parents:
23121
diff
changeset
|
217 if(lavc_param_abitrate<1000) |
74eb6825d332
allow to specify the audio bitrate in bits (some codecs need that ...)
michael
parents:
23121
diff
changeset
|
218 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
|
219 else |
74eb6825d332
allow to specify the audio bitrate in bits (some codecs need that ...)
michael
parents:
23121
diff
changeset
|
220 lavc_actx->bit_rate = encoder->params.bitrate = lavc_param_abitrate; |
15234 | 221 |
222 | |
223 /* | |
224 * Special case for adpcm_ima_wav. | |
22316
f3d7a1b58a82
cosmetics: Fix some common typos, appropiate --> appropRiate,
diego
parents:
21966
diff
changeset
|
225 * The bitrate is only dependent on samplerate. |
15234 | 226 * We have to known frame_size and block_align in advance, |
227 * so I just copied the code from libavcodec/adpcm.c | |
228 * | |
229 * However, ms adpcm_ima_wav uses a block_align of 2048, | |
230 * lavc defaults to 1024 | |
231 */ | |
232 if(lavc_param_atag == 0x11) { | |
233 int blkalign = 2048; | |
234 int framesize = (blkalign - 4 * lavc_actx->channels) * 8 / (4 * lavc_actx->channels) + 1; | |
235 lavc_actx->bit_rate = lavc_actx->sample_rate*8*blkalign/framesize; | |
236 } | |
17842 | 237 if((lavc_param_audio_global_header&1) |
238 /*|| (video_global_header==0 && (oc->oformat->flags & AVFMT_GLOBALHEADER))*/){ | |
239 lavc_actx->flags |= CODEC_FLAG_GLOBAL_HEADER; | |
240 } | |
241 if(lavc_param_audio_global_header&2){ | |
242 lavc_actx->flags2 |= CODEC_FLAG2_LOCAL_HEADER; | |
243 } | |
15234 | 244 |
245 if(avcodec_open(lavc_actx, lavc_acodec) < 0) | |
246 { | |
247 mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_CouldntOpenCodec, lavc_param_acodec, lavc_param_abitrate); | |
248 return 0; | |
249 } | |
250 | |
251 if(lavc_param_atag == 0x11) { | |
252 lavc_actx->block_align = 2048; | |
253 lavc_actx->frame_size = (lavc_actx->block_align - 4 * lavc_actx->channels) * 8 / (4 * lavc_actx->channels) + 1; | |
254 } | |
255 | |
256 encoder->decode_buffer_size = lavc_actx->frame_size * 2 * encoder->params.channels; | |
257 encoder->bind = bind_lavc; | |
258 encoder->get_frame_size = get_frame_size; | |
259 encoder->encode = encode_lavc; | |
260 encoder->close = close_lavc; | |
261 | |
262 return 1; | |
263 } | |
264 |