aboutsummaryrefslogtreecommitdiffstats
path: root/libavformat/swf.c
diff options
context:
space:
mode:
authorBaptiste Coudurier <baptiste.coudurier@gmail.com>2007-03-04 22:30:25 +0000
committerBaptiste Coudurier <baptiste.coudurier@gmail.com>2007-03-04 22:30:25 +0000
commit013e0a8f35b5551675a8c3b9a025ae34e2991b17 (patch)
tree4a367f7bb01e39e861087e96734b5726c6c92baf /libavformat/swf.c
parent44e76d6e3b85c71afb6f3174071194eccd2a69dd (diff)
downloadffmpeg-013e0a8f35b5551675a8c3b9a025ae34e2991b17.tar.gz
simplify swf muxer
Originally committed as revision 8223 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat/swf.c')
-rw-r--r--libavformat/swf.c162
1 files changed, 26 insertions, 136 deletions
diff --git a/libavformat/swf.c b/libavformat/swf.c
index 145c77cb8f..8dba80da75 100644
--- a/libavformat/swf.c
+++ b/libavformat/swf.c
@@ -71,7 +71,7 @@ typedef struct {
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 @@ static const AVCodecTag swf_audio_codec_tags[] = {
{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 @@ static int swf_write_header(AVFormatContext *s)
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 @@ static int swf_write_header(AVFormatContext *s)
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 @@ static int swf_write_video(AVFormatContext *s,
{
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 @@ retry_swf_audio_packet:
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 @@ static int swf_write_audio(AVFormatContext *s,
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 @@ static int swf_write_trailer(AVFormatContext *s)
put_le16(pb, video_enc->frame_number);
url_fseek(pb, file_size, SEEK_SET);
}
-
- av_free(swf->audio_fifo);
-
return 0;
}
#endif //CONFIG_MUXERS