* Moving FifoBuffer out of libavformat/avformat.h and
authorRoman Shaposhnik <roman@shaposhnik.org>
Thu, 21 Sep 2006 07:31:53 +0000 (07:31 +0000)
committerRoman Shaposhnik <roman@shaposhnik.org>
Thu, 21 Sep 2006 07:31:53 +0000 (07:31 +0000)
     libavformat/utils.c into libavutil

Originally committed as revision 6310 to svn://svn.ffmpeg.org/ffmpeg/trunk

ffmpeg.c
libavformat/avformat.h
libavformat/dvenc.c
libavformat/gxfenc.c
libavformat/mpeg.c
libavformat/utils.c
libavutil/Makefile
libavutil/fifo.c [new file with mode: 0644]
libavutil/fifo.h [new file with mode: 0644]

index cf60ed4..76a41cd 100644 (file)
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -23,6 +23,7 @@
 #include "framehook.h"
 #include "dsputil.h"
 #include "opt.h"
+#include "fifo.h"
 
 #ifndef __MINGW32__
 #include <unistd.h>
@@ -267,7 +268,7 @@ typedef struct AVOutputStream {
     /* audio only */
     int audio_resample;
     ReSampleContext *resample; /* for audio resampling */
-    FifoBuffer fifo;     /* for compression: one audio fifo per codec */
+    AVFifoBuffer fifo;     /* for compression: one audio fifo per codec */
     FILE *logfile;
 } AVOutputStream;
 
@@ -471,7 +472,7 @@ static void do_audio_out(AVFormatContext *s,
 
     if(audio_sync_method){
         double delta = get_sync_ipts(ost) * enc->sample_rate - ost->sync_opts
-                - fifo_size(&ost->fifo, ost->fifo.rptr)/(ost->st->codec->channels * 2);
+                - av_fifo_size(&ost->fifo)/(ost->st->codec->channels * 2);
         double idelta= delta*ist->st->codec->sample_rate / enc->sample_rate;
         int byte_delta= ((int)idelta)*2*ist->st->codec->channels;
 
@@ -508,13 +509,13 @@ static void do_audio_out(AVFormatContext *s,
                 assert(ost->audio_resample);
                 if(verbose > 2)
                     fprintf(stderr, "compensating audio timestamp drift:%f compensation:%d in:%d\n", delta, comp, enc->sample_rate);
-//                fprintf(stderr, "drift:%f len:%d opts:%lld ipts:%lld fifo:%d\n", delta, -1, ost->sync_opts, (int64_t)(get_sync_ipts(ost) * enc->sample_rate), fifo_size(&ost->fifo, ost->fifo.rptr)/(ost->st->codec->channels * 2));
+//                fprintf(stderr, "drift:%f len:%d opts:%lld ipts:%lld fifo:%d\n", delta, -1, ost->sync_opts, (int64_t)(get_sync_ipts(ost) * enc->sample_rate), av_fifo_size(&ost->fifo)/(ost->st->codec->channels * 2));
                 av_resample_compensate(*(struct AVResampleContext**)ost->resample, comp, enc->sample_rate);
             }
         }
     }else
         ost->sync_opts= lrintf(get_sync_ipts(ost) * enc->sample_rate)
-                        - fifo_size(&ost->fifo, ost->fifo.rptr)/(ost->st->codec->channels * 2); //FIXME wrong
+                        - av_fifo_size(&ost->fifo)/(ost->st->codec->channels * 2); //FIXME wrong
 
     if (ost->audio_resample) {
         buftmp = audio_buf;
@@ -530,13 +531,11 @@ static void do_audio_out(AVFormatContext *s,
     /* now encode as many frames as possible */
     if (enc->frame_size > 1) {
         /* output resampled raw samples */
-        fifo_write(&ost->fifo, buftmp, size_out,
-                   &ost->fifo.wptr);
+        av_fifo_write(&ost->fifo, buftmp, size_out);
 
         frame_bytes = enc->frame_size * 2 * enc->channels;
 
-        while (fifo_read(&ost->fifo, audio_buf, frame_bytes,
-                     &ost->fifo.rptr) == 0) {
+        while (av_fifo_read(&ost->fifo, audio_buf, frame_bytes) == 0) {
             AVPacket pkt;
             av_init_packet(&pkt);
 
@@ -1317,14 +1316,13 @@ static int output_packet(AVInputStream *ist, int ist_index,
 
                         switch(ost->st->codec->codec_type) {
                         case CODEC_TYPE_AUDIO:
-                            fifo_bytes = fifo_size(&ost->fifo, NULL);
+                            fifo_bytes = av_fifo_size(&ost->fifo);
                             ret = 0;
                             /* encode any samples remaining in fifo */
                             if(fifo_bytes > 0 && enc->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) {
                                 int fs_tmp = enc->frame_size;
                                 enc->frame_size = fifo_bytes / (2 * enc->channels);
-                                if(fifo_read(&ost->fifo, (uint8_t *)samples, fifo_bytes,
-                                        &ost->fifo.rptr) == 0) {
+                                if(av_fifo_read(&ost->fifo, (uint8_t *)samples, fifo_bytes) == 0) {
                                     ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, samples);
                                 }
                                 enc->frame_size = fs_tmp;
@@ -1563,7 +1561,7 @@ static int av_encode(AVFormatContext **output_files,
         } else {
             switch(codec->codec_type) {
             case CODEC_TYPE_AUDIO:
-                if (fifo_init(&ost->fifo, 2 * MAX_AUDIO_PACKET_SIZE))
+                if (av_fifo_init(&ost->fifo, 2 * MAX_AUDIO_PACKET_SIZE))
                     goto fail;
 
                 if (codec->channels == icodec->channels &&
@@ -2018,8 +2016,8 @@ static int av_encode(AVFormatContext **output_files,
                     fclose(ost->logfile);
                     ost->logfile = NULL;
                 }
-                fifo_free(&ost->fifo); /* works even if fifo is not
-                                          initialized but set to zero */
+                av_fifo_free(&ost->fifo); /* works even if fifo is not
+                                             initialized but set to zero */
                 av_free(ost->pict_tmp.data[0]);
                 if (ost->video_resample)
                     sws_freeContext(ost->img_resample_ctx);
index 90c4f49..102dc92 100644 (file)
@@ -441,29 +441,6 @@ void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload);
 
 void av_register_all(void);
 
-typedef struct FifoBuffer {
-    uint8_t *buffer;
-    uint8_t *rptr, *wptr, *end;
-} FifoBuffer;
-
-int fifo_init(FifoBuffer *f, int size);
-void fifo_free(FifoBuffer *f);
-int fifo_size(FifoBuffer *f, uint8_t *rptr);
-int fifo_read(FifoBuffer *f, uint8_t *buf, int buf_size, uint8_t **rptr_ptr);
-void fifo_write(FifoBuffer *f, const uint8_t *buf, int size, uint8_t **wptr_ptr);
-int put_fifo(ByteIOContext *pb, FifoBuffer *f, int buf_size, uint8_t **rptr_ptr);
-void fifo_realloc(FifoBuffer *f, unsigned int size);
-static inline uint8_t fifo_peek(FifoBuffer *f, int offs)
-{
-    return f->buffer[(f->rptr - f->buffer + offs) % (f->end - f->buffer)];
-}
-static inline void fifo_drain(FifoBuffer *f, int size)
-{
-    f->rptr += size;
-    if (f->rptr >= f->end)
-        f->rptr = f->buffer + (f->rptr - f->end);
-}
-
 /* media file input */
 AVInputFormat *av_find_input_format(const char *short_name);
 AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened);
index 17024fb..fd4025c 100644 (file)
 #include "avformat.h"
 #include "dvdata.h"
 #include "dv.h"
+#include "fifo.h"
 
 struct DVMuxContext {
     const DVprofile*  sys;    /* Current DV profile. E.g.: 525/60, 625/50 */
     int         n_ast;        /* Number of stereo audio streams (up to 2) */
     AVStream   *ast[2];       /* Stereo audio streams */
-    FifoBuffer  audio_data[2]; /* Fifo for storing excessive amounts of PCM */
+    AVFifoBuffer  audio_data[2]; /* Fifo for storing excessive amounts of PCM */
     int         frames;       /* Number of a current frame */
     time_t      start_time;   /* Start time of recording */
     int         has_audio;    /* frame under contruction has audio */
@@ -185,8 +186,8 @@ static void dv_inject_audio(DVMuxContext *c, int channel, uint8_t* frame_ptr)
              if (of*2 >= size)
                  continue;
 
-             frame_ptr[d] = fifo_peek(&c->audio_data[channel], of*2+1); // FIXME: may be we have to admit
-             frame_ptr[d+1] = fifo_peek(&c->audio_data[channel], of*2); //        that DV is a big endian PCM
+             frame_ptr[d] = av_fifo_peek(&c->audio_data[channel], of*2+1); // FIXME: may be we have to admit
+             frame_ptr[d+1] = av_fifo_peek(&c->audio_data[channel], of*2); //        that DV is a big endian PCM
           }
           frame_ptr += 16 * 80; /* 15 Video DIFs + 1 Audio DIF */
        }
@@ -247,12 +248,12 @@ int dv_assemble_frame(DVMuxContext *c, AVStream* st,
           for (i = 0; i < c->n_ast && st != c->ast[i]; i++);
 
           /* FIXME: we have to have more sensible approach than this one */
-          if (fifo_size(&c->audio_data[i], c->audio_data[i].rptr) + data_size >= 100*AVCODEC_MAX_AUDIO_FRAME_SIZE)
+          if (av_fifo_size(&c->audio_data[i]) + data_size >= 100*AVCODEC_MAX_AUDIO_FRAME_SIZE)
               av_log(st->codec, AV_LOG_ERROR, "Can't process DV frame #%d. Insufficient video data or severe sync problem.\n", c->frames);
-          fifo_write(&c->audio_data[i], data, data_size, &c->audio_data[i].wptr);
+          av_fifo_write(&c->audio_data[i], data, data_size);
 
           /* Lets see if we've got enough audio for one DV frame */
-          c->has_audio |= ((reqasize <= fifo_size(&c->audio_data[i], c->audio_data[i].rptr)) << i);
+          c->has_audio |= ((reqasize <= av_fifo_size(&c->audio_data[i])) << i);
 
           break;
     default:
@@ -264,7 +265,7 @@ int dv_assemble_frame(DVMuxContext *c, AVStream* st,
         dv_inject_metadata(c, *frame);
         for (i=0; i<c->n_ast; i++) {
              dv_inject_audio(c, i, *frame);
-             fifo_drain(&c->audio_data[i], reqasize);
+             av_fifo_drain(&c->audio_data[i], reqasize);
         }
 
         c->has_video = 0;
@@ -333,10 +334,10 @@ DVMuxContext* dv_init_mux(AVFormatContext* s)
     c->start_time = (time_t)s->timestamp;
 
     for (i=0; i<c->n_ast; i++) {
-        if (c->ast[i] && fifo_init(&c->audio_data[i], 100*AVCODEC_MAX_AUDIO_FRAME_SIZE) < 0) {
+        if (c->ast[i] && av_fifo_init(&c->audio_data[i], 100*AVCODEC_MAX_AUDIO_FRAME_SIZE) < 0) {
             while (i>0) {
                 i--;
-                fifo_free(&c->audio_data[i]);
+                av_fifo_free(&c->audio_data[i]);
             }
             goto bail_out;
         }
@@ -353,7 +354,7 @@ void dv_delete_mux(DVMuxContext *c)
 {
     int i;
     for (i=0; i < c->n_ast; i++)
-        fifo_free(&c->audio_data[i]);
+        av_fifo_free(&c->audio_data[i]);
 }
 
 #ifdef CONFIG_MUXERS
index 234e0a5..6fa7e96 100644 (file)
 #include "avformat.h"
 #include "gxf.h"
 #include "riff.h"
+#include "fifo.h"
 
 #define GXF_AUDIO_PACKET_SIZE 65536
 
 typedef struct GXFStreamContext {
     AVCodecContext *codec;
-    FifoBuffer audio_buffer;
+    AVFifoBuffer audio_buffer;
     uint32_t track_type;
     uint32_t sample_size;
     uint32_t sample_rate;
@@ -604,7 +605,7 @@ static int gxf_write_header(AVFormatContext *s)
             sc->fields = -2;
             gxf->audio_tracks++;
             gxf->flags |= 0x04000000; /* audio is 16 bit pcm */
-            fifo_init(&sc->audio_buffer, 3*GXF_AUDIO_PACKET_SIZE);
+            av_fifo_init(&sc->audio_buffer, 3*GXF_AUDIO_PACKET_SIZE);
         } else if (sc->codec->codec_type == CODEC_TYPE_VIDEO) {
             /* FIXME check from time_base ? */
             if (sc->codec->height == 480 || sc->codec->height == 512) { /* NTSC or NTSC+VBI */
@@ -670,7 +671,7 @@ static int gxf_write_trailer(AVFormatContext *s)
 
     for (i = 0; i < s->nb_streams; ++i) {
         if (s->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO) {
-            fifo_free(&gxf->streams[i].audio_buffer);
+            av_fifo_free(&gxf->streams[i].audio_buffer);
         }
         if (s->streams[i]->codec->frame_number > gxf->nb_frames)
             gxf->nb_frames = 2 * s->streams[i]->codec->frame_number;
@@ -762,12 +763,12 @@ static int gxf_write_packet(AVFormatContext *s, AVPacket *pkt)
 
 static int gxf_new_audio_packet(GXFContext *gxf, GXFStreamContext *sc, AVPacket *pkt, int flush)
 {
-    int size = flush ? fifo_size(&sc->audio_buffer, NULL) : GXF_AUDIO_PACKET_SIZE;
+    int size = flush ? av_fifo_size(&sc->audio_buffer) : GXF_AUDIO_PACKET_SIZE;
 
     if (!size)
         return 0;
     av_new_packet(pkt, size);
-    fifo_read(&sc->audio_buffer, pkt->data, size, NULL);
+    av_fifo_read(&sc->audio_buffer, pkt->data, size);
     pkt->stream_index = sc->index;
     pkt->dts = sc->current_dts;
     sc->current_dts += size / 2; /* we only support 16 bit pcm mono for now */
@@ -784,10 +785,10 @@ static int gxf_interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *pk
         if (s->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO) {
             GXFStreamContext *sc = &gxf->streams[i];
             if (pkt && pkt->stream_index == i) {
-                fifo_write(&sc->audio_buffer, pkt->data, pkt->size, NULL);
+                av_fifo_write(&sc->audio_buffer, pkt->data, pkt->size);
                 pkt = NULL;
             }
-            if (flush || fifo_size(&sc->audio_buffer, NULL) >= GXF_AUDIO_PACKET_SIZE) {
+            if (flush || av_fifo_size(&sc->audio_buffer) >= GXF_AUDIO_PACKET_SIZE) {
                 if (gxf_new_audio_packet(gxf, sc, &new_pkt, flush) > 0) {
                     pkt = &new_pkt;
                     break; /* add pkt right now into list */
index 8846a59..7b965ba 100644 (file)
@@ -18,6 +18,7 @@
  */
 #include "avformat.h"
 #include "bitstream.h"
+#include "fifo.h"
 
 #define MAX_PAYLOAD_SIZE 4096
 //#define DEBUG_SEEK
@@ -35,7 +36,7 @@ typedef struct PacketDesc {
 } PacketDesc;
 
 typedef struct {
-    FifoBuffer fifo;
+    AVFifoBuffer fifo;
     uint8_t id;
     int max_buffer_size; /* in bytes */
     int buffer_index;
@@ -45,7 +46,7 @@ typedef struct {
     int packet_number;
     uint8_t lpcm_header[3];
     int lpcm_align;
-    uint8_t *fifo_iframe_ptr;
+    int bytes_to_iframe;
     int align_iframe;
     int64_t vobu_start_pts;
 } StreamInfo;
@@ -412,7 +413,7 @@ static int mpeg_mux_init(AVFormatContext *ctx)
         default:
             return -1;
         }
-        fifo_init(&stream->fifo, 16);
+        av_fifo_init(&stream->fifo, 16);
     }
     bitrate = 0;
     audio_bitrate = 0;
@@ -708,14 +709,7 @@ static int flush_packet(AVFormatContext *ctx, int stream_index,
             }
         } else if (s->is_dvd) {
             if (stream->align_iframe || s->packet_number == 0){
-                int bytes_to_iframe;
-                int PES_bytes_to_fill;
-                if (stream->fifo_iframe_ptr >= stream->fifo.rptr) {
-                    bytes_to_iframe = stream->fifo_iframe_ptr - stream->fifo.rptr;
-                } else {
-                    bytes_to_iframe = (stream->fifo.end - stream->fifo.rptr) + (stream->fifo_iframe_ptr - stream->fifo.buffer);
-                }
-                PES_bytes_to_fill = s->packet_size - size - 10;
+                int PES_bytes_to_fill = s->packet_size - size - 10;
 
                 if (pts != AV_NOPTS_VALUE) {
                     if (dts != pts)
@@ -724,7 +718,7 @@ static int flush_packet(AVFormatContext *ctx, int stream_index,
                         PES_bytes_to_fill -= 5;
                 }
 
-                if (bytes_to_iframe == 0 || s->packet_number == 0) {
+                if (stream->bytes_to_iframe == 0 || s->packet_number == 0) {
                     size = put_system_header(ctx, buf_ptr, 0);
                     buf_ptr += size;
                     size = buf_ptr - buffer;
@@ -751,8 +745,8 @@ static int flush_packet(AVFormatContext *ctx, int stream_index,
                     s->last_scr= scr;
                     buf_ptr += size;
                     /* GOP Start */
-                } else if (bytes_to_iframe < PES_bytes_to_fill) {
-                    pad_packet_bytes = PES_bytes_to_fill - bytes_to_iframe;
+                } else if (stream->bytes_to_iframe < PES_bytes_to_fill) {
+                    pad_packet_bytes = PES_bytes_to_fill - stream->bytes_to_iframe;
                 }
             }
         } else {
@@ -824,7 +818,7 @@ static int flush_packet(AVFormatContext *ctx, int stream_index,
             startcode = 0x100 + id;
         }
 
-        stuffing_size = payload_size - fifo_size(&stream->fifo, stream->fifo.rptr);
+        stuffing_size = payload_size - av_fifo_size(&stream->fifo);
 
         // first byte doesnt fit -> reset pts/dts + stuffing
         if(payload_size <= trailer_size && pts != AV_NOPTS_VALUE){
@@ -951,8 +945,9 @@ static int flush_packet(AVFormatContext *ctx, int stream_index,
         }
 
         /* output data */
-        if(put_fifo(&ctx->pb, &stream->fifo, payload_size - stuffing_size, &stream->fifo.rptr) < 0)
+        if(av_fifo_generic_read(&stream->fifo, payload_size - stuffing_size, &put_buffer, &ctx->pb) < 0)
             return -1;
+        stream->bytes_to_iframe -= payload_size - stuffing_size;
     }else{
         payload_size=
         stuffing_size= 0;
@@ -1065,7 +1060,7 @@ retry:
     for(i=0; i<ctx->nb_streams; i++){
         AVStream *st = ctx->streams[i];
         StreamInfo *stream = st->priv_data;
-        const int avail_data=  fifo_size(&stream->fifo, stream->fifo.rptr);
+        const int avail_data=  av_fifo_size(&stream->fifo);
         const int space= stream->max_buffer_size - stream->buffer_index;
         int rel_space= 1024*space / stream->max_buffer_size;
         PacketDesc *next_pkt= stream->premux_packet;
@@ -1125,7 +1120,7 @@ retry:
     st = ctx->streams[best_i];
     stream = st->priv_data;
 
-    assert(fifo_size(&stream->fifo, stream->fifo.rptr) > 0);
+    assert(av_fifo_size(&stream->fifo) > 0);
 
     assert(avail_space >= s->packet_size || ignore_constraints);
 
@@ -1141,7 +1136,7 @@ retry:
 //av_log(ctx, AV_LOG_DEBUG, "dts:%f pts:%f scr:%f stream:%d\n", timestamp_packet->dts/90000.0, timestamp_packet->pts/90000.0, scr/90000.0, best_i);
         es_size= flush_packet(ctx, best_i, timestamp_packet->pts, timestamp_packet->dts, scr, trailer_size);
     }else{
-        assert(fifo_size(&stream->fifo, stream->fifo.rptr) == trailer_size);
+        assert(av_fifo_size(&stream->fifo) == trailer_size);
         es_size= flush_packet(ctx, best_i, AV_NOPTS_VALUE, AV_NOPTS_VALUE, scr, trailer_size);
     }
 
@@ -1204,11 +1199,11 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt)
         stream->predecode_packet= pkt_desc;
     stream->next_packet= &pkt_desc->next;
 
-    fifo_realloc(&stream->fifo, fifo_size(&stream->fifo, NULL) + size + 1);
+    av_fifo_realloc(&stream->fifo, av_fifo_size(&stream->fifo) + size + 1);
 
     if (s->is_dvd){
         if (is_iframe && (s->packet_number == 0 || (pts - stream->vobu_start_pts >= 36000))) { // min VOBU length 0.4 seconds (mpucoder)
-            stream->fifo_iframe_ptr = stream->fifo.wptr;
+            stream->bytes_to_iframe = av_fifo_size(&stream->fifo);
             stream->align_iframe = 1;
             stream->vobu_start_pts = pts;
         } else {
@@ -1216,7 +1211,7 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt)
         }
     }
 
-    fifo_write(&stream->fifo, buf, size, &stream->fifo.wptr);
+    av_fifo_write(&stream->fifo, buf, size);
 
     for(;;){
         int ret= output_packet(ctx, 0);
@@ -1248,8 +1243,8 @@ static int mpeg_mux_end(AVFormatContext *ctx)
     for(i=0;i<ctx->nb_streams;i++) {
         stream = ctx->streams[i]->priv_data;
 
-        assert(fifo_size(&stream->fifo, stream->fifo.rptr) == 0);
-        fifo_free(&stream->fifo);
+        assert(av_fifo_size(&stream->fifo) == 0);
+        av_fifo_free(&stream->fifo);
     }
     return 0;
 }
index 77bc84a..425db9a 100644 (file)
@@ -263,146 +263,6 @@ int av_dup_packet(AVPacket *pkt)
     return 0;
 }
 
-/* fifo handling */
-
-int fifo_init(FifoBuffer *f, int size)
-{
-    f->buffer = av_malloc(size);
-    if (!f->buffer)
-        return -1;
-    f->end = f->buffer + size;
-    f->wptr = f->rptr = f->buffer;
-    return 0;
-}
-
-void fifo_free(FifoBuffer *f)
-{
-    av_free(f->buffer);
-}
-
-int fifo_size(FifoBuffer *f, uint8_t *rptr)
-{
-    int size;
-
-    if(!rptr)
-        rptr= f->rptr;
-
-    if (f->wptr >= rptr) {
-        size = f->wptr - rptr;
-    } else {
-        size = (f->end - rptr) + (f->wptr - f->buffer);
-    }
-    return size;
-}
-
-/**
- * Get data from the fifo (returns -1 if not enough data).
- */
-int fifo_read(FifoBuffer *f, uint8_t *buf, int buf_size, uint8_t **rptr_ptr)
-{
-    uint8_t *rptr;
-    int size, len;
-
-    if(!rptr_ptr)
-        rptr_ptr= &f->rptr;
-    rptr = *rptr_ptr;
-
-    if (f->wptr >= rptr) {
-        size = f->wptr - rptr;
-    } else {
-        size = (f->end - rptr) + (f->wptr - f->buffer);
-    }
-
-    if (size < buf_size)
-        return -1;
-    while (buf_size > 0) {
-        len = f->end - rptr;
-        if (len > buf_size)
-            len = buf_size;
-        memcpy(buf, rptr, len);
-        buf += len;
-        rptr += len;
-        if (rptr >= f->end)
-            rptr = f->buffer;
-        buf_size -= len;
-    }
-    *rptr_ptr = rptr;
-    return 0;
-}
-
-/**
- * Resizes a FIFO.
- */
-void fifo_realloc(FifoBuffer *f, unsigned int new_size){
-    unsigned int old_size= f->end - f->buffer;
-
-    if(old_size < new_size){
-        uint8_t *old= f->buffer;
-
-        f->buffer= av_realloc(f->buffer, new_size);
-
-        f->rptr += f->buffer - old;
-        f->wptr += f->buffer - old;
-
-        if(f->wptr < f->rptr){
-            memmove(f->rptr + new_size - old_size, f->rptr, f->buffer + old_size - f->rptr);
-            f->rptr += new_size - old_size;
-        }
-        f->end= f->buffer + new_size;
-    }
-}
-
-void fifo_write(FifoBuffer *f, const uint8_t *buf, int size, uint8_t **wptr_ptr)
-{
-    int len;
-    uint8_t *wptr;
-
-    if(!wptr_ptr)
-        wptr_ptr= &f->wptr;
-    wptr = *wptr_ptr;
-
-    while (size > 0) {
-        len = f->end - wptr;
-        if (len > size)
-            len = size;
-        memcpy(wptr, buf, len);
-        wptr += len;
-        if (wptr >= f->end)
-            wptr = f->buffer;
-        buf += len;
-        size -= len;
-    }
-    *wptr_ptr = wptr;
-}
-
-/* get data from the fifo (return -1 if not enough data) */
-int put_fifo(ByteIOContext *pb, FifoBuffer *f, int buf_size, uint8_t **rptr_ptr)
-{
-    uint8_t *rptr = *rptr_ptr;
-    int size, len;
-
-    if (f->wptr >= rptr) {
-        size = f->wptr - rptr;
-    } else {
-        size = (f->end - rptr) + (f->wptr - f->buffer);
-    }
-
-    if (size < buf_size)
-        return -1;
-    while (buf_size > 0) {
-        len = f->end - rptr;
-        if (len > buf_size)
-            len = buf_size;
-        put_buffer(pb, rptr, len);
-        rptr += len;
-        if (rptr >= f->end)
-            rptr = f->buffer;
-        buf_size -= len;
-    }
-    *rptr_ptr = rptr;
-    return 0;
-}
-
 /**
  * Allocate the payload of a packet and intialized its fields to default values.
  *
index 5b78adc..0450414 100644 (file)
@@ -16,9 +16,10 @@ OBJS= mathematics.o \
       adler32.o \
       log.o \
       mem.o \
+      fifo.o \
 
 HEADERS = avutil.h common.h mathematics.h integer.h rational.h \
-          intfloat_readwrite.h md5.h adler32.h log.h
+          intfloat_readwrite.h md5.h adler32.h log.h fifo.h
 
 NAME=avutil
 ifeq ($(BUILD_SHARED),yes)
diff --git a/libavutil/fifo.c b/libavutil/fifo.c
new file mode 100644 (file)
index 0000000..7746182
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * A very simple circular buffer FIFO implementation
+ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
+ * Copyright (c) 2006 Roman Shaposhnik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include "common.h"
+#include "fifo.h"
+
+int av_fifo_init(AVFifoBuffer *f, int size)
+{
+    f->buffer = av_malloc(size);
+    if (!f->buffer)
+        return -1;
+    f->end = f->buffer + size;
+    f->wptr = f->rptr = f->buffer;
+    return 0;
+}
+
+void av_fifo_free(AVFifoBuffer *f)
+{
+    av_free(f->buffer);
+}
+
+int av_fifo_size(AVFifoBuffer *f)
+{
+    int size = f->wptr - f->rptr;
+    if (size < 0)
+        size += f->end - f->buffer;
+    return size;
+}
+
+/**
+ * Get data from the fifo (returns -1 if not enough data).
+ */
+int av_fifo_read(AVFifoBuffer *f, uint8_t *buf, int buf_size)
+{
+    int len;
+    int size = f->wptr - f->rptr;
+    if (size < 0)
+        size += f->end - f->buffer;
+
+    if (size < buf_size)
+        return -1;
+    while (buf_size > 0) {
+        len = FFMIN(f->end - f->rptr, buf_size);
+        memcpy(buf, f->rptr, len);
+        buf += len;
+        f->rptr += len;
+        if (f->rptr >= f->end)
+            f->rptr = f->buffer;
+        buf_size -= len;
+    }
+    return 0;
+}
+
+/**
+ * Resizes a FIFO.
+ */
+void av_fifo_realloc(AVFifoBuffer *f, unsigned int new_size) {
+    unsigned int old_size= f->end - f->buffer;
+
+    if(old_size < new_size){
+        uint8_t *old= f->buffer;
+
+        f->buffer= av_realloc(f->buffer, new_size);
+
+        f->rptr += f->buffer - old;
+        f->wptr += f->buffer - old;
+
+        if(f->wptr < f->rptr){
+            memmove(f->rptr + new_size - old_size, f->rptr, f->buffer + old_size - f->rptr);
+            f->rptr += new_size - old_size;
+        }
+        f->end= f->buffer + new_size;
+    }
+}
+
+void av_fifo_write(AVFifoBuffer *f, const uint8_t *buf, int size)
+{
+    int len;
+
+    while (size > 0) {
+        len = FFMIN(f->end - f->wptr, size);
+        memcpy(f->wptr, buf, len);
+        f->wptr += len;
+        if (f->wptr >= f->end)
+            f->wptr = f->buffer;
+        buf += len;
+        size -= len;
+    }
+}
+
+
+/* get data from the fifo (return -1 if not enough data) */
+int av_fifo_generic_read(AVFifoBuffer *f, int buf_size, void (*func)(void*, void*, int), void* dest)
+{
+    int len;
+    int size = f->wptr - f->rptr;
+    if (size < 0)
+        size += f->end - f->buffer;
+
+    if (size < buf_size)
+        return -1;
+    while (buf_size > 0) {
+        len = FFMIN(f->end - f->rptr, buf_size);
+        func(dest, f->rptr, len);
+        f->rptr += len;
+        if (f->rptr >= f->end)
+            f->rptr = f->buffer;
+        buf_size -= len;
+    }
+    return 0;
+}
+
+/* discard data from the fifo */
+void av_fifo_drain(AVFifoBuffer *f, int size)
+{
+    f->rptr += size;
+    if (f->rptr >= f->end)
+        f->rptr -= f->end - f->buffer;
+}
diff --git a/libavutil/fifo.h b/libavutil/fifo.h
new file mode 100644 (file)
index 0000000..9dec0e6
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef FIFO_H
+#define FIFO_H
+
+typedef struct AVFifoBuffer {
+    uint8_t *buffer;
+    uint8_t *rptr, *wptr, *end;
+} AVFifoBuffer;
+
+int av_fifo_init(AVFifoBuffer *f, int size);
+void av_fifo_free(AVFifoBuffer *f);
+int av_fifo_size(AVFifoBuffer *f);
+int av_fifo_read(AVFifoBuffer *f, uint8_t *buf, int buf_size);
+int av_fifo_generic_read(AVFifoBuffer *f, int buf_size, void (*func)(void*, void*, int), void* dest);
+void av_fifo_write(AVFifoBuffer *f, const uint8_t *buf, int size);
+void av_fifo_realloc(AVFifoBuffer *f, unsigned int size);
+void av_fifo_drain(AVFifoBuffer *f, int size);
+
+static inline uint8_t av_fifo_peek(AVFifoBuffer *f, int offs)
+{
+    uint8_t *ptr = f->rptr + offs;
+    if (ptr >= f->end)
+        ptr -= f->end - f->buffer;
+    return *ptr;
+}
+#endif /* FIFO_H */