Mercurial > mplayer.hg
annotate libmpcodecs/ae_lavc.c @ 18049:77a3b0d11ca5
Limit the number of entires to the amount that does fit into the chunk.
the function need rewrite as it assumes quite many things that are not guaranteed by the specifications.
author | iive |
---|---|
date | Thu, 06 Apr 2006 20:04:02 +0000 |
parents | 4b1930c9345c |
children | d4d72e5eea07 |
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" |
15234 | 9 #include "aviheader.h" |
10 #include "ms_hdr.h" | |
11 #include "muxer.h" | |
12 #include "ae_lavc.h" | |
13 #include "help_mp.h" | |
17012 | 14 #include "config.h" |
15 #include "libaf/af_format.h" | |
15234 | 16 #ifdef USE_LIBAVCODEC_SO |
17 #include <ffmpeg/avcodec.h> | |
18 #else | |
19 #include "libavcodec/avcodec.h" | |
20 #endif | |
21 | |
22 static AVCodec *lavc_acodec; | |
23 static AVCodecContext *lavc_actx; | |
24 extern char *lavc_param_acodec; | |
25 extern int lavc_param_abitrate; | |
26 extern int lavc_param_atag; | |
17842 | 27 extern int lavc_param_audio_global_header; |
15234 | 28 extern int avcodec_inited; |
29 static int compressed_frame_size = 0; | |
17354 | 30 #if defined(USE_LIBAVFORMAT) || defined(USE_LIBAVFORMAT_SO) |
17096 | 31 extern unsigned int codec_get_wav_tag(int id); |
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); | |
41 mux_a->h.dwRate = mux_a->wf->nAvgBytesPerSec; | |
42 if(lavc_actx->block_align) | |
43 mux_a->h.dwSampleSize = mux_a->h.dwScale = lavc_actx->block_align; | |
44 else | |
45 { | |
46 mux_a->h.dwScale = (mux_a->wf->nAvgBytesPerSec * lavc_actx->frame_size)/ mux_a->wf->nSamplesPerSec; /* for cbr */ | |
47 | |
48 if ((mux_a->wf->nAvgBytesPerSec * | |
49 lavc_actx->frame_size) % mux_a->wf->nSamplesPerSec) | |
50 { | |
51 mux_a->h.dwScale = lavc_actx->frame_size; | |
52 mux_a->h.dwRate = lavc_actx->sample_rate; | |
53 mux_a->h.dwSampleSize = 0; // Blocksize not constant | |
54 } | |
55 else | |
56 mux_a->h.dwSampleSize = mux_a->h.dwScale; | |
57 } | |
58 mux_a->wf->nBlockAlign = mux_a->h.dwScale; | |
59 mux_a->h.dwSuggestedBufferSize = (encoder->params.audio_preload*mux_a->wf->nAvgBytesPerSec)/1000; | |
60 mux_a->h.dwSuggestedBufferSize -= mux_a->h.dwSuggestedBufferSize % mux_a->wf->nBlockAlign; | |
61 | |
62 switch(lavc_param_atag) | |
63 { | |
64 case 0x11: /* imaadpcm */ | |
65 mux_a->wf->wBitsPerSample = 4; | |
66 mux_a->wf->cbSize = 2; | |
67 ((uint16_t*)mux_a->wf)[sizeof(WAVEFORMATEX)] = | |
68 ((lavc_actx->block_align - 4 * lavc_actx->channels) / (4 * lavc_actx->channels)) * 8 + 1; | |
69 break; | |
70 case 0x55: /* mp3 */ | |
71 mux_a->wf->cbSize = 12; | |
72 mux_a->wf->wBitsPerSample = 0; /* does not apply */ | |
73 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->wID = 1; | |
74 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->fdwFlags = 2; | |
75 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nBlockSize = mux_a->wf->nBlockAlign; | |
76 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nFramesPerBlock = 1; | |
77 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nCodecDelay = 0; | |
78 break; | |
79 default: | |
80 mux_a->wf->wBitsPerSample = 0; /* Unknown */ | |
81 if (lavc_actx->extradata && (lavc_actx->extradata_size > 0)) | |
82 { | |
15501
7cdc07507650
wrong memcpy of extradata; 10l to whomever wrote that broken code
nicodvb
parents:
15244
diff
changeset
|
83 memcpy(mux_a->wf+1, lavc_actx->extradata, lavc_actx->extradata_size); |
15234 | 84 mux_a->wf->cbSize = lavc_actx->extradata_size; |
85 } | |
86 else | |
87 mux_a->wf->cbSize = 0; | |
88 break; | |
89 } | |
90 | |
91 // Fix allocation | |
92 mux_a->wf = realloc(mux_a->wf, sizeof(WAVEFORMATEX)+mux_a->wf->cbSize); | |
93 | |
94 encoder->input_format = AF_FORMAT_S16_NE; | |
95 encoder->min_buffer_size = mux_a->h.dwSuggestedBufferSize; | |
96 encoder->max_buffer_size = mux_a->h.dwSuggestedBufferSize*2; | |
97 | |
98 return 1; | |
99 } | |
100 | |
101 static int encode_lavc(audio_encoder_t *encoder, uint8_t *dest, void *src, int size, int max_size) | |
102 { | |
103 int n; | |
104 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
|
105 compressed_frame_size = n; |
15234 | 106 return n; |
107 } | |
108 | |
109 | |
110 static int close_lavc(audio_encoder_t *encoder) | |
111 { | |
112 compressed_frame_size = 0; | |
113 return 1; | |
114 } | |
115 | |
116 static int get_frame_size(audio_encoder_t *encoder) | |
117 { | |
17855
4b1930c9345c
do not randomly chop up packets, this isnt allowed in almost no container
michael
parents:
17842
diff
changeset
|
118 int sz = compressed_frame_size; |
4b1930c9345c
do not randomly chop up packets, this isnt allowed in almost no container
michael
parents:
17842
diff
changeset
|
119 compressed_frame_size = 0; |
4b1930c9345c
do not randomly chop up packets, this isnt allowed in almost no container
michael
parents:
17842
diff
changeset
|
120 return sz; |
15234 | 121 } |
122 | |
15244
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
123 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
|
124 { |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
125 if(codec == NULL) |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
126 return 0; |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
127 |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
128 if(! strcasecmp(codec, "mp2")) |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
129 return 0x50; |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
130 |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
131 if(! strcasecmp(codec, "mp3")) |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
132 return 0x55; |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
133 |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
134 if(! strcasecmp(codec, "ac3")) |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
135 return 0x2000; |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
136 |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
137 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
|
138 return 0x11; |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
139 |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
140 if(! strncasecmp(codec, "bonk", 4)) |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
141 return 0x2048; |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
142 |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
143 return 0; |
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 |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
146 |
15234 | 147 int mpae_init_lavc(audio_encoder_t *encoder) |
148 { | |
149 encoder->params.samples_per_frame = encoder->params.sample_rate; | |
150 encoder->params.bitrate = encoder->params.sample_rate * encoder->params.channels * 2 * 8; | |
151 | |
152 if(!lavc_param_acodec) | |
153 { | |
154 mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_NoLavcAudioCodecName); | |
155 return 0; | |
156 } | |
157 | |
158 if(!avcodec_inited){ | |
159 avcodec_init(); | |
160 avcodec_register_all(); | |
161 avcodec_inited=1; | |
162 } | |
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 { | |
17354 | 172 #if defined(USE_LIBAVFORMAT) || defined(USE_LIBAVFORMAT_SO) |
15234 | 173 lavc_param_atag = codec_get_wav_tag(lavc_acodec->id); |
15244
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
174 #else |
a8a8a4d69a1c
restore old lavc_find_atag to be used when compiling mplayer without libavformat
nicodvb
parents:
15240
diff
changeset
|
175 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
|
176 #endif |
15234 | 177 if(!lavc_param_atag) |
178 { | |
179 mp_msg(MSGT_MENCODER, MSGL_FATAL, "Couldn't find wav tag for specified codec, exit\n"); | |
180 return 0; | |
181 } | |
182 } | |
183 | |
184 lavc_actx = avcodec_alloc_context(); | |
185 if(lavc_actx == NULL) | |
186 { | |
187 mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_CouldntAllocateLavcContext); | |
188 return 0; | |
189 } | |
190 | |
191 // put sample parameters | |
192 lavc_actx->channels = encoder->params.channels; | |
193 lavc_actx->sample_rate = encoder->params.sample_rate; | |
194 lavc_actx->bit_rate = encoder->params.bitrate = lavc_param_abitrate * 1000; | |
195 | |
196 | |
197 /* | |
198 * Special case for adpcm_ima_wav. | |
199 * The bitrate is only dependant on samplerate. | |
200 * We have to known frame_size and block_align in advance, | |
201 * so I just copied the code from libavcodec/adpcm.c | |
202 * | |
203 * However, ms adpcm_ima_wav uses a block_align of 2048, | |
204 * lavc defaults to 1024 | |
205 */ | |
206 if(lavc_param_atag == 0x11) { | |
207 int blkalign = 2048; | |
208 int framesize = (blkalign - 4 * lavc_actx->channels) * 8 / (4 * lavc_actx->channels) + 1; | |
209 lavc_actx->bit_rate = lavc_actx->sample_rate*8*blkalign/framesize; | |
210 } | |
17842 | 211 if((lavc_param_audio_global_header&1) |
212 /*|| (video_global_header==0 && (oc->oformat->flags & AVFMT_GLOBALHEADER))*/){ | |
213 lavc_actx->flags |= CODEC_FLAG_GLOBAL_HEADER; | |
214 } | |
215 if(lavc_param_audio_global_header&2){ | |
216 lavc_actx->flags2 |= CODEC_FLAG2_LOCAL_HEADER; | |
217 } | |
15234 | 218 |
219 if(avcodec_open(lavc_actx, lavc_acodec) < 0) | |
220 { | |
221 mp_msg(MSGT_MENCODER, MSGL_FATAL, MSGTR_CouldntOpenCodec, lavc_param_acodec, lavc_param_abitrate); | |
222 return 0; | |
223 } | |
224 | |
225 if(lavc_param_atag == 0x11) { | |
226 lavc_actx->block_align = 2048; | |
227 lavc_actx->frame_size = (lavc_actx->block_align - 4 * lavc_actx->channels) * 8 / (4 * lavc_actx->channels) + 1; | |
228 } | |
229 | |
230 encoder->decode_buffer_size = lavc_actx->frame_size * 2 * encoder->params.channels; | |
231 encoder->bind = bind_lavc; | |
232 encoder->get_frame_size = get_frame_size; | |
233 encoder->encode = encode_lavc; | |
234 encoder->close = close_lavc; | |
235 | |
236 return 1; | |
237 } | |
238 |