changeset 2091:02a4fd7c606c libavcodec

flush audio encoder buffers at the end fix vorbis in nut again
author michael
date Tue, 22 Jun 2004 21:14:01 +0000
parents 869805505b30
children 58b6b0ce1c20
files avcodec.h mp3lameaudio.c oggvorbis.c utils.c
diffstat 4 files changed, 39 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/avcodec.h	Mon Jun 21 01:01:44 2004 +0000
+++ b/avcodec.h	Tue Jun 22 21:14:01 2004 +0000
@@ -294,6 +294,8 @@
 #define CODEC_CAP_TRUNCATED       0x0008
 /* codec can export data for HW decoding (XvMC) */
 #define CODEC_CAP_HWACCEL         0x0010
+/** codec has a non zero delay and needs to be feeded with NULL at the end to get the delayed data */
+#define CODEC_CAP_DELAY           0x0020
 
 //the following defines might change, so dont expect compatibility if u use them
 #define MB_TYPE_INTRA4x4   0x0001
--- a/mp3lameaudio.c	Mon Jun 21 01:01:44 2004 +0000
+++ b/mp3lameaudio.c	Tue Jun 22 21:14:01 2004 +0000
@@ -136,7 +136,9 @@
 	int lame_result;
 
 	/* lame 3.91 dies on '1-channel interleaved' data */
-	if (s->stereo) {
+
+    if(data){
+        if (s->stereo) {
             lame_result = lame_encode_buffer_interleaved(
                 s->gfp, 
                 data,
@@ -144,7 +146,7 @@
                 s->buffer + s->buffer_index, 
                 BUFFER_SIZE - s->buffer_index
                 );
-	} else {
+        } else {
             lame_result = lame_encode_buffer(
                 s->gfp, 
                 data, 
@@ -153,6 +155,13 @@
                 s->buffer + s->buffer_index, 
                 BUFFER_SIZE - s->buffer_index
                 );
+        }
+    }else{
+        lame_result= lame_encode_flush(
+                s->gfp, 
+                s->buffer + s->buffer_index, 
+                BUFFER_SIZE - s->buffer_index
+                );
     }
 
     if(lame_result==-1) {
@@ -174,7 +183,6 @@
 
             memmove(s->buffer, s->buffer+len, s->buffer_index);
             //FIXME fix the audio codec API, so we dont need the memcpy()
-            //FIXME fix the audio codec API, so we can output multiple packets if we have them
 /*for(i=0; i<len; i++){
     av_log(avctx, AV_LOG_DEBUG, "%2X ", frame[i]);
 }*/
@@ -201,5 +209,6 @@
     sizeof(Mp3AudioContext),
     MP3lame_encode_init,
     MP3lame_encode_frame,
-    MP3lame_encode_close
+    MP3lame_encode_close,
+    .capabilities= CODEC_CAP_DELAY,
 };
--- a/oggvorbis.c	Mon Jun 21 01:01:44 2004 +0000
+++ b/oggvorbis.c	Tue Jun 22 21:14:01 2004 +0000
@@ -21,7 +21,6 @@
     vorbis_block vb ;
     uint8_t buffer[BUFFER_SIZE];
     int buffer_index;
-    int64_t fake_pts; //pts which libavformat will guess, HACK FIXME
 
     /* decoder */
     vorbis_comment vc ;
@@ -104,7 +103,7 @@
     float **buffer ;
     ogg_packet op ;
     signed char *audio = data ;
-    int l, samples = OGGVORBIS_FRAME_SIZE ;
+    int l, samples = data ? OGGVORBIS_FRAME_SIZE : 0;
 
     buffer = vorbis_analysis_buffer(&context->vd, samples) ;
 
@@ -125,6 +124,8 @@
 	vorbis_bitrate_addblock(&context->vb) ;
 
 	while(vorbis_bitrate_flushpacket(&context->vd, &op)) {
+            if(op.bytes==1) //id love to say this is a hack, bad sadly its not, appearently the end of stream decission is in libogg
+                continue;
             memcpy(context->buffer + context->buffer_index, &op, sizeof(ogg_packet));
             context->buffer_index += sizeof(ogg_packet);
             memcpy(context->buffer + context->buffer_index, op.packet, op.bytes);
@@ -138,21 +139,15 @@
         ogg_packet *op2= (ogg_packet*)context->buffer;
         op2->packet = context->buffer + sizeof(ogg_packet);
 
-        if(op2->granulepos <= context->fake_pts /*&& (context->fake_pts || context->buffer_index > 4*1024)*/){
-            assert(op2->granulepos == context->fake_pts);
-            l=  op2->bytes;
+        l=  op2->bytes;
+        avccontext->coded_frame->pts= av_rescale(op2->granulepos, AV_TIME_BASE, avccontext->sample_rate);
 
-            memcpy(packets, op2->packet, l);
-            context->buffer_index -= l + sizeof(ogg_packet);
-            memcpy(context->buffer, context->buffer + l + sizeof(ogg_packet), context->buffer_index);
-        }
+        memcpy(packets, op2->packet, l);
+        context->buffer_index -= l + sizeof(ogg_packet);
+        memcpy(context->buffer, context->buffer + l + sizeof(ogg_packet), context->buffer_index);
 //        av_log(avccontext, AV_LOG_DEBUG, "E%d\n", l);
     }
 
-    if(l || context->fake_pts){
-        context->fake_pts += avccontext->frame_size;
-    }
-        
     return l;
 }
 
@@ -163,19 +158,6 @@
     
     vorbis_analysis_wrote(&context->vd, 0) ; /* notify vorbisenc this is EOF */
 
-    /* We need to write all the remaining packets into the stream
-     * on closing */
-    
-    av_log(avccontext, AV_LOG_ERROR, "fixme: not all packets written on oggvorbis_encode_close()\n") ;
-
-/*
-    while(vorbis_bitrate_flushpacket(&context->vd, &op)) {
-	memcpy(packets + l, &op, sizeof(ogg_packet)) ;
-	memcpy(packets + l + sizeof(ogg_packet), op.packet, op.bytes) ;
-	l += sizeof(ogg_packet) + op.bytes ;	
-    }
-*/
-
     vorbis_block_clear(&context->vb);
     vorbis_dsp_clear(&context->vd);
     vorbis_info_clear(&context->vi);
@@ -194,7 +176,8 @@
     sizeof(OggVorbisContext),
     oggvorbis_encode_init,
     oggvorbis_encode_frame,
-    oggvorbis_encode_close
+    oggvorbis_encode_close,
+    .capabilities= CODEC_CAP_DELAY,
 } ;
 
 
@@ -313,4 +296,5 @@
     NULL,
     oggvorbis_decode_close,
     oggvorbis_decode_frame,
+    .capabilities= CODEC_CAP_DELAY,
 } ;
--- a/utils.c	Mon Jun 21 01:01:44 2004 +0000
+++ b/utils.c	Tue Jun 22 21:14:01 2004 +0000
@@ -453,24 +453,25 @@
 int avcodec_encode_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size, 
                          const short *samples)
 {
-    int ret;
-
-    ret = avctx->codec->encode(avctx, buf, buf_size, (void *)samples);
-    avctx->frame_number++;
-    return ret;
+    if((avctx->codec->capabilities & CODEC_CAP_DELAY) || samples){
+        int ret = avctx->codec->encode(avctx, buf, buf_size, (void *)samples);
+        avctx->frame_number++;
+        return ret;
+    }else
+        return 0;
 }
 
 int avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size, 
                          const AVFrame *pict)
 {
-    int ret;
-
-    ret = avctx->codec->encode(avctx, buf, buf_size, (void *)pict);
+    if((avctx->codec->capabilities & CODEC_CAP_DELAY) || pict){
+        int ret = avctx->codec->encode(avctx, buf, buf_size, (void *)pict);
+        avctx->frame_number++;
+        emms_c(); //needed to avoid a emms_c() call before every return;
     
-    emms_c(); //needed to avoid a emms_c() call before every return;
-
-    avctx->frame_number++;
-    return ret;
+        return ret;
+    }else
+        return 0;
 }
 
 /**