changeset 445:c1f88671135b libavformat

cleanup fix streamcopy
author michael
date Sat, 17 Apr 2004 12:04:59 +0000
parents d42038d418a0
children 35447449b8b4
files flvdec.c flvenc.c
diffstat 2 files changed, 115 insertions(+), 150 deletions(-) [+]
line wrap: on
line diff
--- 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;i<s->nb_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)
--- 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 <assert.h>
+
 #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 (;c<size;c++) {
-                flv->audioFifo[(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 (;c<mp3FrameSize;c++) {
-                        frame->data[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;