Mercurial > mplayer.hg
annotate libmpcodecs/ae_lavc.c @ 32972:fbaae7fe1a13
Fix several issues with Translate().
1. The "Unsafe!" comment has been removed, because the strings passed
to the function are strcpy'd.
2. The needless memsets (one of which with wrong size) have been removed
in favor of a sufficiently simple initialization of trbuf.
3. The array indices are unsigned now, and the manual optimization of
having strlen() outside the for loop has been removed in favor of
optimization performed by the compiler.
4. There is a check now to prevent an out-of-bounds array access.
author | ib |
---|---|
date | Tue, 08 Mar 2011 20:56:51 +0000 |
parents | 44f4ead8fdb0 |
children | 281e1b1ae34c |
rev | line source |
---|---|
30421
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29673
diff
changeset
|
1 /* |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29673
diff
changeset
|
2 * This file is part of MPlayer. |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29673
diff
changeset
|
3 * |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29673
diff
changeset
|
4 * MPlayer is free software; you can redistribute it and/or modify |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29673
diff
changeset
|
5 * it under the terms of the GNU General Public License as published by |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29673
diff
changeset
|
6 * the Free Software Foundation; either version 2 of the License, or |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29673
diff
changeset
|
7 * (at your option) any later version. |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29673
diff
changeset
|
8 * |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29673
diff
changeset
|
9 * MPlayer is distributed in the hope that it will be useful, |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29673
diff
changeset
|
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29673
diff
changeset
|
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29673
diff
changeset
|
12 * GNU General Public License for more details. |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29673
diff
changeset
|
13 * |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29673
diff
changeset
|
14 * You should have received a copy of the GNU General Public License along |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29673
diff
changeset
|
15 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29673
diff
changeset
|
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29673
diff
changeset
|
17 */ |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29673
diff
changeset
|
18 |
15234 | 19 #include <stdio.h> |
20 #include <stdlib.h> | |
21 #include <inttypes.h> | |
15238 | 22 #include <unistd.h> |
15234 | 23 #include <string.h> |
15240 | 24 #include <sys/types.h> |
26203 | 25 #include "config.h" |
15234 | 26 #include "m_option.h" |
17012 | 27 #include "mp_msg.h" |
22601
ed8f90096c65
Add explicit location for headers from the libmpdemux/ directory.
diego
parents:
22600
diff
changeset
|
28 #include "libmpdemux/aviheader.h" |
ed8f90096c65
Add explicit location for headers from the libmpdemux/ directory.
diego
parents:
22600
diff
changeset
|
29 #include "libmpdemux/ms_hdr.h" |
22600
3c2b4a866c6a
Add explicit location for headers from the stream/ directory.
diego
parents:
22316
diff
changeset
|
30 #include "stream/stream.h" |
22601
ed8f90096c65
Add explicit location for headers from the libmpdemux/ directory.
diego
parents:
22600
diff
changeset
|
31 #include "libmpdemux/muxer.h" |
15234 | 32 #include "ae_lavc.h" |
31959
f957f330aa6d
Introduce init_avcodec function to avoid duplicated FFmpeg initializations.
diego
parents:
31589
diff
changeset
|
33 #include "vd_ffmpeg.h" |
32017 | 34 #include "ve.h" |
15234 | 35 #include "help_mp.h" |
31589
ef92321146a1
Make it possible to set all options for lavc audio encoder.
reimar
parents:
30633
diff
changeset
|
36 #include "av_opts.h" |
17012 | 37 #include "libaf/af_format.h" |
25315
dfa8a510c81c
Fix all current known multi-channel wrong order problems by adding
ulion
parents:
24359
diff
changeset
|
38 #include "libaf/reorder_ch.h" |
15234 | 39 #include "libavcodec/avcodec.h" |
28132 | 40 #include "libavutil/intreadwrite.h" |
32142
4614728cab25
build system: Merge all FFmpeg library checks into a single FFmpeg check.
diego
parents:
32017
diff
changeset
|
41 #include "libavformat/avformat.h" |
4614728cab25
build system: Merge all FFmpeg library checks into a single FFmpeg check.
diego
parents:
32017
diff
changeset
|
42 #include "libmpdemux/mp_taglists.h" |
32907
44f4ead8fdb0
Start adding support for lavc audio encoders that use other formats
reimar
parents:
32768
diff
changeset
|
43 #include "fmt-conversion.h" |
15234 | 44 |
45 static AVCodec *lavc_acodec; | |
46 static AVCodecContext *lavc_actx; | |
47 static int compressed_frame_size = 0; | |
48 | |
49 static int bind_lavc(audio_encoder_t *encoder, muxer_stream_t *mux_a) | |
50 { | |
51 mux_a->wf = malloc(sizeof(WAVEFORMATEX)+lavc_actx->extradata_size+256); | |
52 mux_a->wf->wFormatTag = lavc_param_atag; | |
53 mux_a->wf->nChannels = lavc_actx->channels; | |
54 mux_a->wf->nSamplesPerSec = lavc_actx->sample_rate; | |
55 mux_a->wf->nAvgBytesPerSec = (lavc_actx->bit_rate / 8); | |
19360
d4d72e5eea07
pass average bitrate from encoder to (lavf) muxer
michael
parents:
17855
diff
changeset
|
56 mux_a->avg_rate= lavc_actx->bit_rate; |
15234 | 57 mux_a->h.dwRate = mux_a->wf->nAvgBytesPerSec; |
58 if(lavc_actx->block_align) | |
59 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
|
60 else |
15234 | 61 { |
62 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
|
63 |
15234 | 64 if ((mux_a->wf->nAvgBytesPerSec * |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28928
diff
changeset
|
65 lavc_actx->frame_size) % mux_a->wf->nSamplesPerSec) |
15234 | 66 { |
67 mux_a->h.dwScale = lavc_actx->frame_size; | |
68 mux_a->h.dwRate = lavc_actx->sample_rate; | |
69 mux_a->h.dwSampleSize = 0; // Blocksize not constant | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28928
diff
changeset
|
70 } |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28928
diff
changeset
|
71 else |
21773
03bc990498fc
the avi spec does not allow random samplesize whoever wrote this should be shot
michael
parents:
21771
diff
changeset
|
72 mux_a->h.dwSampleSize = 0; |
15234 | 73 } |
21773
03bc990498fc
the avi spec does not allow random samplesize whoever wrote this should be shot
michael
parents:
21771
diff
changeset
|
74 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
|
75 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
|
76 else |
03bc990498fc
the avi spec does not allow random samplesize whoever wrote this should be shot
michael
parents:
21771
diff
changeset
|
77 mux_a->wf->nBlockAlign = 1; |
15234 | 78 mux_a->h.dwSuggestedBufferSize = (encoder->params.audio_preload*mux_a->wf->nAvgBytesPerSec)/1000; |
79 mux_a->h.dwSuggestedBufferSize -= mux_a->h.dwSuggestedBufferSize % mux_a->wf->nBlockAlign; | |
80 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28928
diff
changeset
|
81 switch(lavc_param_atag) |
15234 | 82 { |
83 case 0x11: /* imaadpcm */ | |
84 mux_a->wf->wBitsPerSample = 4; | |
85 mux_a->wf->cbSize = 2; | |
28132 | 86 AV_WL16(mux_a->wf+1, lavc_actx->frame_size); |
15234 | 87 break; |
88 case 0x55: /* mp3 */ | |
89 mux_a->wf->cbSize = 12; | |
90 mux_a->wf->wBitsPerSample = 0; /* does not apply */ | |
91 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->wID = 1; | |
92 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->fdwFlags = 2; | |
93 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nBlockSize = mux_a->wf->nBlockAlign; | |
94 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nFramesPerBlock = 1; | |
95 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nCodecDelay = 0; | |
96 break; | |
97 default: | |
98 mux_a->wf->wBitsPerSample = 0; /* Unknown */ | |
99 if (lavc_actx->extradata && (lavc_actx->extradata_size > 0)) | |
100 { | |
15501
7cdc07507650
wrong memcpy of extradata; 10l to whomever wrote that broken code
nicodvb
parents:
15244
diff
changeset
|
101 memcpy(mux_a->wf+1, lavc_actx->extradata, lavc_actx->extradata_size); |
15234 | 102 mux_a->wf->cbSize = lavc_actx->extradata_size; |
103 } | |
104 else | |
105 mux_a->wf->cbSize = 0; | |
106 break; | |
107 } | |
108 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28928
diff
changeset
|
109 // Fix allocation |
15234 | 110 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
|
111 |
15234 | 112 encoder->min_buffer_size = mux_a->h.dwSuggestedBufferSize; |
113 encoder->max_buffer_size = mux_a->h.dwSuggestedBufferSize*2; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28928
diff
changeset
|
114 |
15234 | 115 return 1; |
116 } | |
117 | |
118 static int encode_lavc(audio_encoder_t *encoder, uint8_t *dest, void *src, int size, int max_size) | |
119 { | |
120 int n; | |
25315
dfa8a510c81c
Fix all current known multi-channel wrong order problems by adding
ulion
parents:
24359
diff
changeset
|
121 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
|
122 (!strcmp(lavc_acodec->name,"ac3") || |
dfa8a510c81c
Fix all current known multi-channel wrong order problems by adding
ulion
parents:
24359
diff
changeset
|
123 !strcmp(lavc_acodec->name,"libfaac"))) { |
dfa8a510c81c
Fix all current known multi-channel wrong order problems by adding
ulion
parents:
24359
diff
changeset
|
124 int isac3 = !strcmp(lavc_acodec->name,"ac3"); |
dfa8a510c81c
Fix all current known multi-channel wrong order problems by adding
ulion
parents:
24359
diff
changeset
|
125 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
|
126 isac3 ? AF_CHANNEL_LAYOUT_LAVC_DEFAULT |
25315
dfa8a510c81c
Fix all current known multi-channel wrong order problems by adding
ulion
parents:
24359
diff
changeset
|
127 : AF_CHANNEL_LAYOUT_AAC_DEFAULT, |
dfa8a510c81c
Fix all current known multi-channel wrong order problems by adding
ulion
parents:
24359
diff
changeset
|
128 encoder->params.channels, |
dfa8a510c81c
Fix all current known multi-channel wrong order problems by adding
ulion
parents:
24359
diff
changeset
|
129 size / 2, 2); |
dfa8a510c81c
Fix all current known multi-channel wrong order problems by adding
ulion
parents:
24359
diff
changeset
|
130 } |
15234 | 131 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
|
132 compressed_frame_size = n; |
15234 | 133 return n; |
134 } | |
135 | |
136 | |
137 static int close_lavc(audio_encoder_t *encoder) | |
138 { | |
139 compressed_frame_size = 0; | |
140 return 1; | |
141 } | |
142 | |
143 static int get_frame_size(audio_encoder_t *encoder) | |
144 { | |
17855
4b1930c9345c
do not randomly chop up packets, this isnt allowed in almost no container
michael
parents:
17842
diff
changeset
|
145 int sz = compressed_frame_size; |
4b1930c9345c
do not randomly chop up packets, this isnt allowed in almost no container
michael
parents:
17842
diff
changeset
|
146 compressed_frame_size = 0; |
4b1930c9345c
do not randomly chop up packets, this isnt allowed in almost no container
michael
parents:
17842
diff
changeset
|
147 return sz; |
15234 | 148 } |
149 | |
15244
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
150 |
15234 | 151 int mpae_init_lavc(audio_encoder_t *encoder) |
152 { | |
153 encoder->params.samples_per_frame = encoder->params.sample_rate; | |
154 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
|
155 |
15234 | 156 if(!lavc_param_acodec) |
157 { | |
158 mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_NoLavcAudioCodecName); | |
159 return 0; | |
160 } | |
161 | |
31959
f957f330aa6d
Introduce init_avcodec function to avoid duplicated FFmpeg initializations.
diego
parents:
31589
diff
changeset
|
162 init_avcodec(); |
15234 | 163 |
164 lavc_acodec = avcodec_find_encoder_by_name(lavc_param_acodec); | |
165 if (!lavc_acodec) | |
166 { | |
167 mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_LavcAudioCodecNotFound, lavc_param_acodec); | |
168 return 0; | |
169 } | |
170 if(lavc_param_atag == 0) | |
171 { | |
21966
d9494ca70ca7
Simplify by using av_codec_get_id and include riff.h only in demux_lavf.c
reimar
parents:
21963
diff
changeset
|
172 lavc_param_atag = av_codec_get_tag(mp_wav_taglists, lavc_acodec->id); |
15234 | 173 if(!lavc_param_atag) |
174 { | |
175 mp_msg(MSGT_MENCODER, MSGL_FATAL, "Couldn't find wav tag for specified codec, exit\n"); | |
176 return 0; | |
177 } | |
178 } | |
179 | |
180 lavc_actx = avcodec_alloc_context(); | |
181 if(lavc_actx == NULL) | |
182 { | |
183 mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_CouldntAllocateLavcContext); | |
184 return 0; | |
185 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28928
diff
changeset
|
186 |
32768
3544ba7244bf
Change deprecated PKT_FLAG_KEY, CODEC_TYPE_* and SAMPLE_FMT_* to their
reimar
parents:
32656
diff
changeset
|
187 lavc_actx->codec_type = AVMEDIA_TYPE_AUDIO; |
29673
a3cc38ad5878
Set codec_type and codec_id in codec context for lavc encoders.
reimar
parents:
29491
diff
changeset
|
188 lavc_actx->codec_id = lavc_acodec->id; |
15234 | 189 // put sample parameters |
32907
44f4ead8fdb0
Start adding support for lavc audio encoders that use other formats
reimar
parents:
32768
diff
changeset
|
190 lavc_actx->sample_fmt = lavc_acodec->sample_fmts ? lavc_acodec->sample_fmts[0] : AV_SAMPLE_FMT_S16; |
44f4ead8fdb0
Start adding support for lavc audio encoders that use other formats
reimar
parents:
32768
diff
changeset
|
191 encoder->input_format = samplefmt2affmt(lavc_actx->sample_fmt); |
15234 | 192 lavc_actx->channels = encoder->params.channels; |
193 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
|
194 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
|
195 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
|
196 if(lavc_param_abitrate<1000) |
74eb6825d332
allow to specify the audio bitrate in bits (some codecs need that ...)
michael
parents:
23121
diff
changeset
|
197 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
|
198 else |
74eb6825d332
allow to specify the audio bitrate in bits (some codecs need that ...)
michael
parents:
23121
diff
changeset
|
199 lavc_actx->bit_rate = encoder->params.bitrate = lavc_param_abitrate; |
31589
ef92321146a1
Make it possible to set all options for lavc audio encoder.
reimar
parents:
30633
diff
changeset
|
200 if(lavc_param_audio_avopt){ |
ef92321146a1
Make it possible to set all options for lavc audio encoder.
reimar
parents:
30633
diff
changeset
|
201 if(parse_avopts(lavc_actx, lavc_param_audio_avopt) < 0){ |
ef92321146a1
Make it possible to set all options for lavc audio encoder.
reimar
parents:
30633
diff
changeset
|
202 mp_msg(MSGT_MENCODER,MSGL_ERR, "Your options /%s/ look like gibberish to me pal\n", lavc_param_audio_avopt); |
ef92321146a1
Make it possible to set all options for lavc audio encoder.
reimar
parents:
30633
diff
changeset
|
203 return 0; |
ef92321146a1
Make it possible to set all options for lavc audio encoder.
reimar
parents:
30633
diff
changeset
|
204 } |
ef92321146a1
Make it possible to set all options for lavc audio encoder.
reimar
parents:
30633
diff
changeset
|
205 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28928
diff
changeset
|
206 |
15234 | 207 |
208 /* | |
209 * Special case for adpcm_ima_wav. | |
22316
f3d7a1b58a82
cosmetics: Fix some common typos, appropiate --> appropRiate,
diego
parents:
21966
diff
changeset
|
210 * The bitrate is only dependent on samplerate. |
15234 | 211 * We have to known frame_size and block_align in advance, |
212 * so I just copied the code from libavcodec/adpcm.c | |
213 * | |
214 * However, ms adpcm_ima_wav uses a block_align of 2048, | |
215 * lavc defaults to 1024 | |
216 */ | |
217 if(lavc_param_atag == 0x11) { | |
218 int blkalign = 2048; | |
219 int framesize = (blkalign - 4 * lavc_actx->channels) * 8 / (4 * lavc_actx->channels) + 1; | |
220 lavc_actx->bit_rate = lavc_actx->sample_rate*8*blkalign/framesize; | |
221 } | |
17842 | 222 if((lavc_param_audio_global_header&1) |
223 /*|| (video_global_header==0 && (oc->oformat->flags & AVFMT_GLOBALHEADER))*/){ | |
224 lavc_actx->flags |= CODEC_FLAG_GLOBAL_HEADER; | |
225 } | |
226 if(lavc_param_audio_global_header&2){ | |
227 lavc_actx->flags2 |= CODEC_FLAG2_LOCAL_HEADER; | |
228 } | |
15234 | 229 |
230 if(avcodec_open(lavc_actx, lavc_acodec) < 0) | |
231 { | |
232 mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_CouldntOpenCodec, lavc_param_acodec, lavc_param_abitrate); | |
233 return 0; | |
234 } | |
235 | |
236 if(lavc_param_atag == 0x11) { | |
237 lavc_actx->block_align = 2048; | |
238 lavc_actx->frame_size = (lavc_actx->block_align - 4 * lavc_actx->channels) * 8 / (4 * lavc_actx->channels) + 1; | |
239 } | |
240 | |
241 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
|
242 while (encoder->decode_buffer_size < 1024) encoder->decode_buffer_size *= 2; |
15234 | 243 encoder->bind = bind_lavc; |
244 encoder->get_frame_size = get_frame_size; | |
245 encoder->encode = encode_lavc; | |
246 encoder->close = close_lavc; | |
247 | |
248 return 1; | |
249 } |