comparison flvenc.c @ 445:c1f88671135b libavformat

cleanup fix streamcopy
author michael
date Sat, 17 Apr 2004 12:04:59 +0000
parents 20f644245408
children 35447449b8b4
comparison
equal deleted inserted replaced
444:d42038d418a0 445:c1f88671135b
16 * License along with this library; if not, write to the Free Software 16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */ 18 */
19 #include "avformat.h" 19 #include "avformat.h"
20 20
21 #undef NDEBUG
22 #include <assert.h>
23
21 #define VIDEO_FIFO_SIZE 512 24 #define VIDEO_FIFO_SIZE 512
22 25
23 typedef struct FLVFrame { 26 typedef struct FLVFrame {
24 int type; 27 int type;
25 int timestamp; 28 int timestamp;
30 } FLVFrame; 33 } FLVFrame;
31 34
32 typedef struct FLVContext { 35 typedef struct FLVContext {
33 int hasAudio; 36 int hasAudio;
34 int hasVideo; 37 int hasVideo;
35 #ifdef CONFIG_MP3LAME
36 int audioTime;
37 int audioInPos;
38 int audioOutPos;
39 int audioSize;
40 // int audioRate;
41 int initDelay; 38 int initDelay;
42 int soundDelay;
43 uint8_t *audioFifo;
44 int64_t sampleCount; 39 int64_t sampleCount;
45 #endif // CONFIG_MP3LAME
46 int64_t frameCount; 40 int64_t frameCount;
47 FLVFrame *frames; 41 FLVFrame *frames;
48 } FLVContext; 42 } FLVContext;
49 43
50
51 #ifdef CONFIG_MP3LAME 44 #ifdef CONFIG_MP3LAME
52
53 #define AUDIO_FIFO_SIZE 65536
54 45
55 static const int sSampleRates[3][4] = { 46 static const int sSampleRates[3][4] = {
56 {44100, 48000, 32000, 0}, 47 {44100, 48000, 32000, 0},
57 {22050, 24000, 16000, 0}, 48 {22050, 24000, 16000, 0},
58 {11025, 12000, 8000, 0}, 49 {11025, 12000, 8000, 0},
136 av_set_pts_info(s, 24, 1, 1000); /* 24 bit pts in ms */ 127 av_set_pts_info(s, 24, 1, 1000); /* 24 bit pts in ms */
137 128
138 flv->hasAudio = 0; 129 flv->hasAudio = 0;
139 flv->hasVideo = 0; 130 flv->hasVideo = 0;
140 131
141 #ifdef CONFIG_MP3LAME
142 flv->audioTime = -1;
143 flv->audioFifo = av_malloc(AUDIO_FIFO_SIZE);
144 flv->audioInPos = 0;
145 flv->audioOutPos = 0;
146 flv->audioSize = 0;
147 // flv->audioRate = 44100;
148 flv->initDelay = -1; 132 flv->initDelay = -1;
149 flv->soundDelay = 0;
150 #endif // CONFIG_MP3LAME
151 133
152 flv->frames = 0; 134 flv->frames = 0;
153 135
154 put_tag(pb,"FLV"); 136 put_tag(pb,"FLV");
155 put_byte(pb,1); 137 put_byte(pb,1);
246 const uint8_t *buf, int size, int64_t timestamp) 228 const uint8_t *buf, int size, int64_t timestamp)
247 { 229 {
248 ByteIOContext *pb = &s->pb; 230 ByteIOContext *pb = &s->pb;
249 AVCodecContext *enc = &s->streams[stream_index]->codec; 231 AVCodecContext *enc = &s->streams[stream_index]->codec;
250 FLVContext *flv = s->priv_data; 232 FLVContext *flv = s->priv_data;
251 233 FLVFrame *frame = av_malloc(sizeof(FLVFrame));
234
235 frame->next = 0;
236 frame->size = size;
237 frame->data = av_malloc(size);
238 frame->timestamp = timestamp;
239 memcpy(frame->data,buf,size);
240
241 // av_log(s, AV_LOG_DEBUG, "type:%d pts: %lld size:%d\n", enc->codec_type, timestamp, size);
242
252 if (enc->codec_type == CODEC_TYPE_VIDEO) { 243 if (enc->codec_type == CODEC_TYPE_VIDEO) {
253 FLVFrame *frame = av_malloc(sizeof(FLVFrame));
254 frame->next = 0;
255 frame->type = 9; 244 frame->type = 9;
256 frame->flags = 2; // choose h263 245 frame->flags = 2; // choose h263
257 frame->flags |= enc->coded_frame->key_frame ? 0x10 : 0x20; // add keyframe indicator 246 frame->flags |= enc->coded_frame->key_frame ? 0x10 : 0x20; // add keyframe indicator
258 frame->timestamp = timestamp;
259 //frame->timestamp = ( ( flv->frameCount * (int64_t)FRAME_RATE_BASE * (int64_t)1000 ) / (int64_t)enc->frame_rate ); 247 //frame->timestamp = ( ( flv->frameCount * (int64_t)FRAME_RATE_BASE * (int64_t)1000 ) / (int64_t)enc->frame_rate );
260 //printf("%08x %f %f\n",frame->timestamp,(double)enc->frame_rate/(double)FRAME_RATE_BASE,1000*(double)FRAME_RATE_BASE/(double)enc->frame_rate); 248 //printf("%08x %f %f\n",frame->timestamp,(double)enc->frame_rate/(double)FRAME_RATE_BASE,1000*(double)FRAME_RATE_BASE/(double)enc->frame_rate);
261 frame->size = size;
262 frame->data = av_malloc(size);
263 memcpy(frame->data,buf,size);
264 flv->hasVideo = 1; 249 flv->hasVideo = 1;
265 250
266 InsertSorted(flv,frame); 251 InsertSorted(flv,frame);
267 252
268 flv->frameCount ++; 253 flv->frameCount ++;
269 } 254 }
270 else if (enc->codec_type == CODEC_TYPE_AUDIO) { 255 else if (enc->codec_type == CODEC_TYPE_AUDIO) {
271 #ifdef CONFIG_MP3LAME 256 int soundFormat = 0x02;
272 if (enc->codec_id == CODEC_ID_MP3 ) { 257
273 int c=0; 258 switch (enc->sample_rate) {
274 259 case 44100:
275 for (;c<size;c++) { 260 soundFormat |= 0x0C;
276 flv->audioFifo[(flv->audioOutPos+c)%AUDIO_FIFO_SIZE] = buf[c]; 261 break;
277 } 262 case 22050:
278 flv->audioSize += size; 263 soundFormat |= 0x08;
279 flv->audioOutPos += size; 264 break;
280 flv->audioOutPos %= AUDIO_FIFO_SIZE; 265 case 11025:
281 266 soundFormat |= 0x04;
282 if ( flv->initDelay == -1 ) { 267 break;
283 flv->initDelay = timestamp; 268 case 8000: //nellymoser only
284 } 269 case 5512: //not mp3
270 soundFormat |= 0x00;
271 break;
272 default:
273 assert(0);
274 }
275
276 if (enc->channels > 1) {
277 soundFormat |= 0x01;
278 }
279
280 switch(enc->codec_id){
281 case CODEC_ID_MP3:
282 soundFormat |= 0x20;
283 break;
284 case 0:
285 soundFormat |= enc->codec_tag<<4;
286 break;
287 default:
288 assert(0);
289 }
290
291 assert(size);
292 if ( flv->initDelay == -1 ) {
293 flv->initDelay = timestamp;
294 }
295
296 frame->type = 8;
297 frame->flags = soundFormat;
285 298
286 // if ( flv->audioTime == -1 ) { 299 // if ( flv->audioTime == -1 ) {
287 flv->audioTime = timestamp;
288 // flv->audioTime = ( ( ( flv->sampleCount - enc->delay ) * 8000 ) / flv->audioRate ) - flv->initDelay - 250; 300 // flv->audioTime = ( ( ( flv->sampleCount - enc->delay ) * 8000 ) / flv->audioRate ) - flv->initDelay - 250;
289 // if ( flv->audioTime < 0 ) { 301 // if ( flv->audioTime < 0 ) {
290 // flv->audioTime = 0; 302 // flv->audioTime = 0;
291 // } 303 // }
292 // } 304 // }
293 } 305
294 for ( ; flv->audioSize >= 4 ; ) { 306 #ifdef CONFIG_MP3LAME
295 307 if (enc->codec_id == CODEC_ID_MP3 ) {
296 int mp3FrameSize = 0; 308 int mp3FrameSize = 0;
297 int mp3SampleRate = 0; 309 int mp3SampleRate = 0;
298 int mp3IsMono = 0; 310 int mp3IsMono = 0;
299 int mp3SamplesPerFrame = 0; 311 int mp3SamplesPerFrame = 0;
300 int c=0;
301 312
302 /* copy out mp3 header from ring buffer */ 313 /* copy out mp3 header from ring buffer */
303 uint8_t header[4]; 314 if(!mp3info(buf,&mp3FrameSize,&mp3SamplesPerFrame,&mp3SampleRate,&mp3IsMono))
304 for (c=0; c<4; c++) { 315 assert(0);
305 header[c] = flv->audioFifo[(flv->audioInPos+c) % AUDIO_FIFO_SIZE]; 316 assert ( size == mp3FrameSize );
306 } 317 assert(enc->sample_rate == mp3SampleRate);
307 318 // assert(enc->frame_size == mp3SamplesPerFrame);
308 if ( mp3info(header,&mp3FrameSize,&mp3SamplesPerFrame,&mp3SampleRate,&mp3IsMono) ) { 319 //av_log(NULL, AV_LOG_DEBUG, "sizes: %d %d\n", enc->frame_size, mp3SamplesPerFrame);
309 if ( flv->audioSize >= mp3FrameSize ) { 320
310 321 frame->timestamp = (1000*flv->sampleCount + enc->sample_rate/2)/(enc->sample_rate);
311 int soundFormat = 0x22; 322 flv->sampleCount += mp3SamplesPerFrame;
312 int c=0;
313 FLVFrame *frame = av_malloc(sizeof(FLVFrame));
314
315 // flv->audioRate = mp3SampleRate;
316
317 switch (mp3SampleRate) {
318 case 44100:
319 soundFormat |= 0x0C;
320 break;
321 case 22050:
322 soundFormat |= 0x08;
323 break;
324 case 11025:
325 soundFormat |= 0x04;
326 break;
327 }
328
329 if ( !mp3IsMono ) {
330 soundFormat |= 0x01;
331 }
332
333 frame->next = 0;
334 frame->type = 8;
335 frame->flags = soundFormat;
336 frame->timestamp = flv->audioTime;
337 frame->timestamp = (1000*flv->sampleCount + mp3SampleRate/2)/(mp3SampleRate);
338 frame->size = mp3FrameSize;
339 frame->data = av_malloc(mp3FrameSize);
340
341 for (;c<mp3FrameSize;c++) {
342 frame->data[c] = flv->audioFifo[(flv->audioInPos+c)%AUDIO_FIFO_SIZE];
343 }
344
345 flv->audioInPos += mp3FrameSize;
346 flv->audioSize -= mp3FrameSize;
347 flv->audioInPos %= AUDIO_FIFO_SIZE;
348 flv->sampleCount += mp3SamplesPerFrame;
349
350 flv->audioTime += 1000*mp3SamplesPerFrame/mp3SampleRate;
351 // We got audio! Make sure we set this to the global flags on closure
352 flv->hasAudio = 1;
353
354 InsertSorted(flv,frame);
355 // av_log(NULL,AV_LOG_DEBUG, "insert sound\n");
356 continue;
357 }
358 // av_log(NULL,AV_LOG_DEBUG, "insuficent data\n");
359 break;
360 }
361 av_log(NULL,AV_LOG_DEBUG, "head trashed\n");
362 flv->audioInPos ++;
363 flv->audioSize --;
364 flv->audioInPos %= AUDIO_FIFO_SIZE;
365 // no audio in here!
366 flv->audioTime = -1;
367 } 323 }
368 #endif 324 #endif
369 } 325
326 // We got audio! Make sure we set this to the global flags on closure
327 flv->hasAudio = 1;
328 InsertSorted(flv,frame);
329 }else
330 assert(0);
370 Dump(flv,pb,128); 331 Dump(flv,pb,128);
371 put_flush_packet(pb); 332 put_flush_packet(pb);
372 return 0; 333 return 0;
373 } 334 }
374 335