summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2004-04-17 12:04:59 +0000
committerMichael Niedermayer <michaelni@gmx.at>2004-04-17 12:04:59 +0000
commit068f2a22db94f9a87a9c5222fc02ea8624bd9e4d (patch)
tree7f945009db5689826b75c2940595273c4039f57b
parentbf17ff617b6c411bcbb92272144f3530858d7c53 (diff)
cleanup
fix streamcopy Originally committed as revision 3026 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r--libavformat/flvdec.c90
-rw-r--r--libavformat/flvenc.c177
2 files changed, 116 insertions, 151 deletions
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index 560cb2860b..c192dd8e43 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -40,8 +40,6 @@ static int flv_probe(AVProbeData *p)
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 @@ static int flv_read_header(AVFormatContext *s,
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_header(AVFormatContext *s,
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 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
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;
}
- 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;
+ if(i == s->nb_streams){
+ st = av_new_stream(s, is_audio);
+ if (!st)
+ return AVERROR_NOMEM;
+ st->codec.frame_rate_base= 0;
}
-
- //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;
+ break;
+ }
+
+ 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 --git a/libavformat/flvenc.c b/libavformat/flvenc.c
index 302fc7602c..ee4b88105c 100644
--- a/libavformat/flvenc.c
+++ b/libavformat/flvenc.c
@@ -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 FLVFrame {
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 @@ static int flv_write_header(AVFormatContext *s)
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 @@ static int flv_write_packet(AVFormatContext *s, int stream_index,
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 @@ static int flv_write_packet(AVFormatContext *s, int stream_index,
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;
- 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;
+ 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);
+ }
- if ( flv->initDelay == -1 ) {
- flv->initDelay = timestamp;
- }
+ 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);
+ }
+
+ 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;
- }
-
- 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;
+ 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->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;