# HG changeset patch # User michael # Date 1082203499 0 # Node ID c1f88671135b94268fce25a649ba0645245bf31e # Parent d42038d418a0ff5c8aa74635a3d36fa9d35fc1b0 cleanup fix streamcopy diff -r d42038d418a0 -r c1f88671135b flvdec.c --- a/flvdec.c Tue Apr 13 13:33:02 2004 +0000 +++ b/flvdec.c Sat Apr 17 12:04:59 2004 +0000 @@ -40,8 +40,6 @@ return 0; } -#define FRAME_RATE_UNKNOWN 31415 //yes i know its beatifull - static int flv_read_header(AVFormatContext *s, AVFormatParameters *ap) { @@ -55,25 +53,6 @@ url_fskip(&s->pb, 4); flags = get_byte(&s->pb); - if ((flags & 1)) { - st = av_new_stream(s, 0); - if (!st) - return AVERROR_NOMEM; - st->codec.codec_type = CODEC_TYPE_VIDEO; - st->codec.codec_id = CODEC_ID_FLV1; - st->codec.frame_rate= FRAME_RATE_UNKNOWN; -// st->codec.frame_rate= ap->frame_rate; -// st->codec.frame_rate_base= ap->frame_rate_base; - } - - if ((flags & 4)) { - st = av_new_stream(s, 1); - if (!st) - return AVERROR_NOMEM; - st->codec.codec_type = CODEC_TYPE_AUDIO; - st->codec.codec_id = CODEC_ID_MP3; - } - offset = get_be32(&s->pb); url_fseek(&s->pb, offset, SEEK_SET); @@ -82,10 +61,10 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) { - int ret, i, type, size, pts, flags; + int ret, i, type, size, pts, flags, is_audio; AVStream *st; - redo: + for(;;){ url_fskip(&s->pb, 4); /* size of previous packet */ type = get_byte(&s->pb); size = get_be24(&s->pb); @@ -95,43 +74,68 @@ return -EIO; url_fskip(&s->pb, 4); /* reserved */ flags = 0; + + if(size == 0) + continue; + if (type == 8) { + is_audio=1; flags = get_byte(&s->pb); size--; - if ((flags >> 4) != 2) { /* 0: uncompressed 1: ADPCM 2: mp3 5: Nellymoser 8kHz mono 6: Nellymoser*/ - goto skip; - } } else if (type == 9) { + is_audio=0; flags = get_byte(&s->pb); size--; - if ((flags & 0xF) != 2) { /* 2: only format */ - goto skip; - } } else { - skip: /* skip packet */ av_log(s, AV_LOG_ERROR, "skipping flv packet: type %d, size %d, flags %d\n", type, size, flags); url_fskip(&s->pb, size); - goto redo; + continue; } /* now find stream */ for(i=0;inb_streams;i++) { st = s->streams[i]; - if (st->id == ((type == 9) ? 0 : 1)) - goto found; + if (st->id == is_audio) + break; + } + if(i == s->nb_streams){ + st = av_new_stream(s, is_audio); + if (!st) + return AVERROR_NOMEM; + st->codec.frame_rate_base= 0; } - goto skip; - found: - if(type == 8 && st->codec.sample_rate == 0){ - st->codec.channels = (flags&1)+1; - st->codec.sample_rate = (44100<<((flags>>2)&3))>>3; - } + break; + } - //guess the frame rate - if(type==9 && st->codec.frame_rate == FRAME_RATE_UNKNOWN && pts){ - st->codec.frame_rate_base=1; - st->codec.frame_rate= (1000 + pts/2)/pts; + if(is_audio){ + if(st->codec.sample_rate == 0){ + st->codec.codec_type = CODEC_TYPE_AUDIO; + st->codec.channels = (flags&1)+1; + if((flags >> 4) == 5) + st->codec.sample_rate= 8000; + else + st->codec.sample_rate = (44100<<((flags>>2)&3))>>3; + switch(flags >> 4){/* 0: uncompressed 1: ADPCM 2: mp3 5: Nellymoser 8kHz mono 6: Nellymoser*/ + case 2: st->codec.codec_id = CODEC_ID_MP3; break; + default: + st->codec.codec_tag= (flags >> 4); + } + } + }else{ + if(st->codec.frame_rate_base == 0){ + st->codec.codec_type = CODEC_TYPE_VIDEO; + //guess the frame rate + if(pts){ + st->codec.frame_rate_base=1; + st->codec.frame_rate= (1000 + pts/2)/pts; + } + switch(flags & 0xF){ + case 2: st->codec.codec_id = CODEC_ID_FLV1; break; + default: + st->codec.codec_tag= flags & 0xF; + } + } } if (av_new_packet(pkt, size) < 0) diff -r d42038d418a0 -r c1f88671135b flvenc.c --- a/flvenc.c Tue Apr 13 13:33:02 2004 +0000 +++ b/flvenc.c Sat Apr 17 12:04:59 2004 +0000 @@ -18,6 +18,9 @@ */ #include "avformat.h" +#undef NDEBUG +#include + #define VIDEO_FIFO_SIZE 512 typedef struct FLVFrame { @@ -32,26 +35,14 @@ typedef struct FLVContext { int hasAudio; int hasVideo; -#ifdef CONFIG_MP3LAME - int audioTime; - int audioInPos; - int audioOutPos; - int audioSize; -// int audioRate; int initDelay; - int soundDelay; - uint8_t *audioFifo; int64_t sampleCount; -#endif // CONFIG_MP3LAME int64_t frameCount; FLVFrame *frames; } FLVContext; - #ifdef CONFIG_MP3LAME -#define AUDIO_FIFO_SIZE 65536 - static const int sSampleRates[3][4] = { {44100, 48000, 32000, 0}, {22050, 24000, 16000, 0}, @@ -138,16 +129,7 @@ flv->hasAudio = 0; flv->hasVideo = 0; -#ifdef CONFIG_MP3LAME - flv->audioTime = -1; - flv->audioFifo = av_malloc(AUDIO_FIFO_SIZE); - flv->audioInPos = 0; - flv->audioOutPos = 0; - flv->audioSize = 0; -// flv->audioRate = 44100; flv->initDelay = -1; - flv->soundDelay = 0; -#endif // CONFIG_MP3LAME flv->frames = 0; @@ -248,19 +230,22 @@ ByteIOContext *pb = &s->pb; AVCodecContext *enc = &s->streams[stream_index]->codec; FLVContext *flv = s->priv_data; + FLVFrame *frame = av_malloc(sizeof(FLVFrame)); + frame->next = 0; + frame->size = size; + frame->data = av_malloc(size); + frame->timestamp = timestamp; + memcpy(frame->data,buf,size); + +// av_log(s, AV_LOG_DEBUG, "type:%d pts: %lld size:%d\n", enc->codec_type, timestamp, size); + if (enc->codec_type == CODEC_TYPE_VIDEO) { - FLVFrame *frame = av_malloc(sizeof(FLVFrame)); - frame->next = 0; frame->type = 9; frame->flags = 2; // choose h263 frame->flags |= enc->coded_frame->key_frame ? 0x10 : 0x20; // add keyframe indicator - frame->timestamp = timestamp; //frame->timestamp = ( ( flv->frameCount * (int64_t)FRAME_RATE_BASE * (int64_t)1000 ) / (int64_t)enc->frame_rate ); //printf("%08x %f %f\n",frame->timestamp,(double)enc->frame_rate/(double)FRAME_RATE_BASE,1000*(double)FRAME_RATE_BASE/(double)enc->frame_rate); - frame->size = size; - frame->data = av_malloc(size); - memcpy(frame->data,buf,size); flv->hasVideo = 1; InsertSorted(flv,frame); @@ -268,105 +253,81 @@ flv->frameCount ++; } else if (enc->codec_type == CODEC_TYPE_AUDIO) { -#ifdef CONFIG_MP3LAME - if (enc->codec_id == CODEC_ID_MP3 ) { - int c=0; + int soundFormat = 0x02; + + switch (enc->sample_rate) { + case 44100: + soundFormat |= 0x0C; + break; + case 22050: + soundFormat |= 0x08; + break; + case 11025: + soundFormat |= 0x04; + break; + case 8000: //nellymoser only + case 5512: //not mp3 + soundFormat |= 0x00; + break; + default: + assert(0); + } - for (;caudioFifo[(flv->audioOutPos+c)%AUDIO_FIFO_SIZE] = buf[c]; - } - flv->audioSize += size; - flv->audioOutPos += size; - flv->audioOutPos %= AUDIO_FIFO_SIZE; + if (enc->channels > 1) { + soundFormat |= 0x01; + } + + switch(enc->codec_id){ + case CODEC_ID_MP3: + soundFormat |= 0x20; + break; + case 0: + soundFormat |= enc->codec_tag<<4; + break; + default: + assert(0); + } - if ( flv->initDelay == -1 ) { - flv->initDelay = timestamp; - } + assert(size); + if ( flv->initDelay == -1 ) { + flv->initDelay = timestamp; + } + + frame->type = 8; + frame->flags = soundFormat; // if ( flv->audioTime == -1 ) { - flv->audioTime = timestamp; // flv->audioTime = ( ( ( flv->sampleCount - enc->delay ) * 8000 ) / flv->audioRate ) - flv->initDelay - 250; // if ( flv->audioTime < 0 ) { // flv->audioTime = 0; // } // } - } - for ( ; flv->audioSize >= 4 ; ) { +#ifdef CONFIG_MP3LAME + if (enc->codec_id == CODEC_ID_MP3 ) { int mp3FrameSize = 0; int mp3SampleRate = 0; int mp3IsMono = 0; int mp3SamplesPerFrame = 0; - int c=0; /* copy out mp3 header from ring buffer */ - uint8_t header[4]; - for (c=0; c<4; c++) { - header[c] = flv->audioFifo[(flv->audioInPos+c) % AUDIO_FIFO_SIZE]; - } - - if ( mp3info(header,&mp3FrameSize,&mp3SamplesPerFrame,&mp3SampleRate,&mp3IsMono) ) { - if ( flv->audioSize >= mp3FrameSize ) { - - int soundFormat = 0x22; - int c=0; - FLVFrame *frame = av_malloc(sizeof(FLVFrame)); - -// flv->audioRate = mp3SampleRate; - - switch (mp3SampleRate) { - case 44100: - soundFormat |= 0x0C; - break; - case 22050: - soundFormat |= 0x08; - break; - case 11025: - soundFormat |= 0x04; - break; - } - - if ( !mp3IsMono ) { - soundFormat |= 0x01; - } + if(!mp3info(buf,&mp3FrameSize,&mp3SamplesPerFrame,&mp3SampleRate,&mp3IsMono)) + assert(0); + assert ( size == mp3FrameSize ); + assert(enc->sample_rate == mp3SampleRate); +// assert(enc->frame_size == mp3SamplesPerFrame); +//av_log(NULL, AV_LOG_DEBUG, "sizes: %d %d\n", enc->frame_size, mp3SamplesPerFrame); - frame->next = 0; - frame->type = 8; - frame->flags = soundFormat; - frame->timestamp = flv->audioTime; - frame->timestamp = (1000*flv->sampleCount + mp3SampleRate/2)/(mp3SampleRate); - frame->size = mp3FrameSize; - frame->data = av_malloc(mp3FrameSize); - - for (;cdata[c] = flv->audioFifo[(flv->audioInPos+c)%AUDIO_FIFO_SIZE]; - } - - flv->audioInPos += mp3FrameSize; - flv->audioSize -= mp3FrameSize; - flv->audioInPos %= AUDIO_FIFO_SIZE; - flv->sampleCount += mp3SamplesPerFrame; - - flv->audioTime += 1000*mp3SamplesPerFrame/mp3SampleRate; - // We got audio! Make sure we set this to the global flags on closure - flv->hasAudio = 1; - - InsertSorted(flv,frame); -// av_log(NULL,AV_LOG_DEBUG, "insert sound\n"); - continue; - } -// av_log(NULL,AV_LOG_DEBUG, "insuficent data\n"); - break; - } - av_log(NULL,AV_LOG_DEBUG, "head trashed\n"); - flv->audioInPos ++; - flv->audioSize --; - flv->audioInPos %= AUDIO_FIFO_SIZE; - // no audio in here! - flv->audioTime = -1; + frame->timestamp = (1000*flv->sampleCount + enc->sample_rate/2)/(enc->sample_rate); + flv->sampleCount += mp3SamplesPerFrame; } #endif - } + + // We got audio! Make sure we set this to the global flags on closure + flv->hasAudio = 1; + InsertSorted(flv,frame); + }else + assert(0); Dump(flv,pb,128); put_flush_packet(pb); return 0;