changeset 1854:0432f6b969b0 libavformat

simplify swf muxer
author bcoudurier
date Sun, 04 Mar 2007 22:30:25 +0000
parents c704f9d730bf
children 908630dcc162
files swf.c
diffstat 1 files changed, 26 insertions(+), 136 deletions(-) [+]
line wrap: on
line diff
--- a/swf.c	Sun Mar 04 11:59:29 2007 +0000
+++ b/swf.c	Sun Mar 04 22:30:25 2007 +0000
@@ -71,7 +71,7 @@
     int ms_per_frame;
     int tag;
 
-    uint8_t *audio_fifo;
+    uint8_t audio_fifo[AUDIO_FIFO_SIZE];
     int audio_in_pos;
     int audio_out_pos;
     int audio_size;
@@ -95,73 +95,6 @@
     {0, 0},
 };
 
-static const int sSampleRates[3][4] = {
-    {44100, 48000, 32000, 0},
-    {22050, 24000, 16000, 0},
-    {11025, 12000,  8000, 0},
-};
-
-static const int sBitRates[2][3][15] = {
-    {   {  0, 32, 64, 96,128,160,192,224,256,288,320,352,384,416,448},
-        {  0, 32, 48, 56, 64, 80, 96,112,128,160,192,224,256,320,384},
-        {  0, 32, 40, 48, 56, 64, 80, 96,112,128,160,192,224,256,320}
-    },
-    {   {  0, 32, 48, 56, 64, 80, 96,112,128,144,160,176,192,224,256},
-        {  0,  8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160},
-        {  0,  8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160}
-    },
-};
-
-static const int sSamplesPerFrame[3][3] =
-{
-    {  384,     1152,    1152 },
-    {  384,     1152,     576 },
-    {  384,     1152,     576 }
-};
-
-static const int sBitsPerSlot[3] = {
-    32,
-    8,
-    8
-};
-
-static int swf_mp3_info(void *data, int *byteSize, int *samplesPerFrame, int *sampleRate, int *isMono )
-{
-    uint32_t header = AV_RB32(data);
-    int layerID = 3 - ((header >> 17) & 0x03);
-    int bitRateID = ((header >> 12) & 0x0f);
-    int sampleRateID = ((header >> 10) & 0x03);
-    int bitRate = 0;
-    int bitsPerSlot = sBitsPerSlot[layerID];
-    int isPadded = ((header >> 9) & 0x01);
-
-    if ( (( header >> 21 ) & 0x7ff) != 0x7ff ) {
-        return 0;
-    }
-
-    *isMono = ((header >>  6) & 0x03) == 0x03;
-
-    if ( (header >> 19 ) & 0x01 ) {
-        *sampleRate = sSampleRates[0][sampleRateID];
-        bitRate = sBitRates[0][layerID][bitRateID] * 1000;
-        *samplesPerFrame = sSamplesPerFrame[0][layerID];
-    } else {
-        if ( (header >> 20) & 0x01 ) {
-            *sampleRate = sSampleRates[1][sampleRateID];
-            bitRate = sBitRates[1][layerID][bitRateID] * 1000;
-            *samplesPerFrame = sSamplesPerFrame[1][layerID];
-        } else {
-            *sampleRate = sSampleRates[2][sampleRateID];
-            bitRate = sBitRates[1][layerID][bitRateID] * 1000;
-            *samplesPerFrame = sSamplesPerFrame[2][layerID];
-        }
-    }
-
-    *byteSize = ( ( ( ( *samplesPerFrame * (bitRate / bitsPerSlot) ) / *sampleRate ) + isPadded ) );
-
-    return 1;
-}
-
 #ifdef CONFIG_MUXERS
 static void put_swf_tag(AVFormatContext *s, int tag)
 {
@@ -323,7 +256,6 @@
     swf->audio_in_pos = 0;
     swf->audio_out_pos = 0;
     swf->audio_size = 0;
-    swf->audio_fifo = av_malloc(AUDIO_FIFO_SIZE);
     swf->sound_samples = 0;
     swf->video_samples = 0;
     swf->swf_frame_number = 0;
@@ -333,9 +265,18 @@
     audio_enc = NULL;
     for(i=0;i<s->nb_streams;i++) {
         enc = s->streams[i]->codec;
-        if (enc->codec_type == CODEC_TYPE_AUDIO)
-            audio_enc = enc;
-        else {
+        if (enc->codec_type == CODEC_TYPE_AUDIO) {
+            if (enc->codec_id == CODEC_ID_MP3) {
+                if (!enc->frame_size) {
+                    av_log(s, AV_LOG_ERROR, "audio frame size not set\n");
+                    return -1;
+                }
+                audio_enc = enc;
+            } else {
+                av_log(enc, AV_LOG_ERROR, "SWF only supports MP3\n");
+                return -1;
+            }
+        } else {
             if ( enc->codec_id == CODEC_ID_VP6F ||
                  enc->codec_id == CODEC_ID_FLV1 ||
                  enc->codec_id == CODEC_ID_MJPEG ) {
@@ -476,55 +417,12 @@
 {
     SWFContext *swf = s->priv_data;
     ByteIOContext *pb = &s->pb;
-    int c = 0;
-    int outSize = 0;
-    int outSamples = 0;
 
     /* Flash Player limit */
     if ( swf->swf_frame_number == 16000 ) {
         av_log(enc, AV_LOG_INFO, "warning: Flash Player limit of 16000 frames reached\n");
     }
 
-    if ( swf->audio_type ) {
-        /* Prescan audio data for this swf frame */
-retry_swf_audio_packet:
-        if ( ( swf->audio_size-outSize ) >= 4 ) {
-            int mp3FrameSize = 0;
-            int mp3SampleRate = 0;
-            int mp3IsMono = 0;
-            int mp3SamplesPerFrame = 0;
-
-            /* copy out mp3 header from ring buffer */
-            uint8_t header[4];
-            for (c=0; c<4; c++) {
-                header[c] = swf->audio_fifo[(swf->audio_in_pos+outSize+c) % AUDIO_FIFO_SIZE];
-            }
-
-            if ( swf_mp3_info(header,&mp3FrameSize,&mp3SamplesPerFrame,&mp3SampleRate,&mp3IsMono) ) {
-                if ( ( swf->audio_size-outSize ) >= mp3FrameSize ) {
-                    outSize += mp3FrameSize;
-                    outSamples += mp3SamplesPerFrame;
-                    if ( ( swf->sound_samples + outSamples + swf->samples_per_frame ) < swf->video_samples ) {
-                        goto retry_swf_audio_packet;
-                    }
-                }
-            } else {
-                /* invalid mp3 data, skip forward
-                we need to do this since the Flash Player
-                does not like custom headers */
-                swf->audio_in_pos ++;
-                swf->audio_size --;
-                swf->audio_in_pos %= AUDIO_FIFO_SIZE;
-                goto retry_swf_audio_packet;
-            }
-        }
-
-        /* audio stream is behind video stream, bail */
-        if ( ( swf->sound_samples + outSamples + swf->samples_per_frame ) < swf->video_samples ) {
-            return 0;
-        }
-    }
-
             if ( swf->video_type == CODEC_ID_VP6F ||
                  swf->video_type == CODEC_ID_FLV1 ) {
                 if ( swf->video_frame_number == 0 ) {
@@ -611,20 +509,16 @@
     swf->video_samples += swf->samples_per_frame;
 
     /* streaming sound always should be placed just before showframe tags */
-    if ( outSize > 0 ) {
+    if (swf->audio_type && swf->audio_in_pos) {
         put_swf_tag(s, TAG_STREAMBLOCK | TAG_LONG);
-        put_le16(pb, outSamples);
-        put_le16(pb, 0);
-        for (c=0; c<outSize; c++) {
-            put_byte(pb,swf->audio_fifo[(swf->audio_in_pos+c) % AUDIO_FIFO_SIZE]);
-        }
+        put_le16(pb, swf->sound_samples);
+        put_le16(pb, 0); // seek samples
+        put_buffer(pb, swf->audio_fifo, swf->audio_in_pos);
         put_swf_end_tag(s);
 
         /* update FIFO */
-        swf->sound_samples += outSamples;
-        swf->audio_in_pos += outSize;
-        swf->audio_size -= outSize;
-        swf->audio_in_pos %= AUDIO_FIFO_SIZE;
+        swf->sound_samples = 0;
+        swf->audio_in_pos = 0;
     }
 
     /* output the frame */
@@ -640,22 +534,21 @@
                            AVCodecContext *enc, const uint8_t *buf, int size)
 {
     SWFContext *swf = s->priv_data;
-    int c = 0;
 
     /* Flash Player limit */
     if ( swf->swf_frame_number == 16000 ) {
         av_log(enc, AV_LOG_INFO, "warning: Flash Player limit of 16000 frames reached\n");
     }
 
-    if (enc->codec_id == CODEC_ID_MP3 ) {
-        for (c=0; c<size; c++) {
-            swf->audio_fifo[(swf->audio_out_pos+c)%AUDIO_FIFO_SIZE] = buf[c];
-        }
-        swf->audio_size += size;
-        swf->audio_out_pos += size;
-        swf->audio_out_pos %= AUDIO_FIFO_SIZE;
+    if (swf->audio_in_pos + size >= AUDIO_FIFO_SIZE) {
+        av_log(s, AV_LOG_ERROR, "audio fifo too small to mux audio essence\n");
+        return -1;
     }
 
+    memcpy(swf->audio_fifo +  swf->audio_in_pos, buf, size);
+    swf->audio_in_pos += size;
+    swf->sound_samples += enc->frame_size;
+
     /* if audio only stream make sure we add swf frames */
     if ( swf->video_type == 0 ) {
         swf_write_video(s, enc, 0, 0);
@@ -701,9 +594,6 @@
         put_le16(pb, video_enc->frame_number);
         url_fseek(pb, file_size, SEEK_SET);
     }
-
-    av_free(swf->audio_fifo);
-
     return 0;
 }
 #endif //CONFIG_MUXERS