Revision f5a478f6

View differences:

ffmpeg.c
23 23
#include "framehook.h"
24 24
#include "dsputil.h"
25 25
#include "opt.h"
26
#include "fifo.h"
26 27

  
27 28
#ifndef __MINGW32__
28 29
#include <unistd.h>
......
267 268
    /* audio only */
268 269
    int audio_resample;
269 270
    ReSampleContext *resample; /* for audio resampling */
270
    FifoBuffer fifo;     /* for compression: one audio fifo per codec */
271
    AVFifoBuffer fifo;     /* for compression: one audio fifo per codec */
271 272
    FILE *logfile;
272 273
} AVOutputStream;
273 274

  
......
471 472

  
472 473
    if(audio_sync_method){
473 474
        double delta = get_sync_ipts(ost) * enc->sample_rate - ost->sync_opts
474
                - fifo_size(&ost->fifo, ost->fifo.rptr)/(ost->st->codec->channels * 2);
475
                - av_fifo_size(&ost->fifo)/(ost->st->codec->channels * 2);
475 476
        double idelta= delta*ist->st->codec->sample_rate / enc->sample_rate;
476 477
        int byte_delta= ((int)idelta)*2*ist->st->codec->channels;
477 478

  
......
508 509
                assert(ost->audio_resample);
509 510
                if(verbose > 2)
510 511
                    fprintf(stderr, "compensating audio timestamp drift:%f compensation:%d in:%d\n", delta, comp, enc->sample_rate);
511
//                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));
512
//                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));
512 513
                av_resample_compensate(*(struct AVResampleContext**)ost->resample, comp, enc->sample_rate);
513 514
            }
514 515
        }
515 516
    }else
516 517
        ost->sync_opts= lrintf(get_sync_ipts(ost) * enc->sample_rate)
517
                        - fifo_size(&ost->fifo, ost->fifo.rptr)/(ost->st->codec->channels * 2); //FIXME wrong
518
                        - av_fifo_size(&ost->fifo)/(ost->st->codec->channels * 2); //FIXME wrong
518 519

  
519 520
    if (ost->audio_resample) {
520 521
        buftmp = audio_buf;
......
530 531
    /* now encode as many frames as possible */
531 532
    if (enc->frame_size > 1) {
532 533
        /* output resampled raw samples */
533
        fifo_write(&ost->fifo, buftmp, size_out,
534
                   &ost->fifo.wptr);
534
        av_fifo_write(&ost->fifo, buftmp, size_out);
535 535

  
536 536
        frame_bytes = enc->frame_size * 2 * enc->channels;
537 537

  
538
        while (fifo_read(&ost->fifo, audio_buf, frame_bytes,
539
                     &ost->fifo.rptr) == 0) {
538
        while (av_fifo_read(&ost->fifo, audio_buf, frame_bytes) == 0) {
540 539
            AVPacket pkt;
541 540
            av_init_packet(&pkt);
542 541

  
......
1317 1316

  
1318 1317
                        switch(ost->st->codec->codec_type) {
1319 1318
                        case CODEC_TYPE_AUDIO:
1320
                            fifo_bytes = fifo_size(&ost->fifo, NULL);
1319
                            fifo_bytes = av_fifo_size(&ost->fifo);
1321 1320
                            ret = 0;
1322 1321
                            /* encode any samples remaining in fifo */
1323 1322
                            if(fifo_bytes > 0 && enc->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) {
1324 1323
                                int fs_tmp = enc->frame_size;
1325 1324
                                enc->frame_size = fifo_bytes / (2 * enc->channels);
1326
                                if(fifo_read(&ost->fifo, (uint8_t *)samples, fifo_bytes,
1327
                                        &ost->fifo.rptr) == 0) {
1325
                                if(av_fifo_read(&ost->fifo, (uint8_t *)samples, fifo_bytes) == 0) {
1328 1326
                                    ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, samples);
1329 1327
                                }
1330 1328
                                enc->frame_size = fs_tmp;
......
1563 1561
        } else {
1564 1562
            switch(codec->codec_type) {
1565 1563
            case CODEC_TYPE_AUDIO:
1566
                if (fifo_init(&ost->fifo, 2 * MAX_AUDIO_PACKET_SIZE))
1564
                if (av_fifo_init(&ost->fifo, 2 * MAX_AUDIO_PACKET_SIZE))
1567 1565
                    goto fail;
1568 1566

  
1569 1567
                if (codec->channels == icodec->channels &&
......
2018 2016
                    fclose(ost->logfile);
2019 2017
                    ost->logfile = NULL;
2020 2018
                }
2021
                fifo_free(&ost->fifo); /* works even if fifo is not
2022
                                          initialized but set to zero */
2019
                av_fifo_free(&ost->fifo); /* works even if fifo is not
2020
                                             initialized but set to zero */
2023 2021
                av_free(ost->pict_tmp.data[0]);
2024 2022
                if (ost->video_resample)
2025 2023
                    sws_freeContext(ost->img_resample_ctx);
libavformat/avformat.h
441 441

  
442 442
void av_register_all(void);
443 443

  
444
typedef struct FifoBuffer {
445
    uint8_t *buffer;
446
    uint8_t *rptr, *wptr, *end;
447
} FifoBuffer;
448

  
449
int fifo_init(FifoBuffer *f, int size);
450
void fifo_free(FifoBuffer *f);
451
int fifo_size(FifoBuffer *f, uint8_t *rptr);
452
int fifo_read(FifoBuffer *f, uint8_t *buf, int buf_size, uint8_t **rptr_ptr);
453
void fifo_write(FifoBuffer *f, const uint8_t *buf, int size, uint8_t **wptr_ptr);
454
int put_fifo(ByteIOContext *pb, FifoBuffer *f, int buf_size, uint8_t **rptr_ptr);
455
void fifo_realloc(FifoBuffer *f, unsigned int size);
456
static inline uint8_t fifo_peek(FifoBuffer *f, int offs)
457
{
458
    return f->buffer[(f->rptr - f->buffer + offs) % (f->end - f->buffer)];
459
}
460
static inline void fifo_drain(FifoBuffer *f, int size)
461
{
462
    f->rptr += size;
463
    if (f->rptr >= f->end)
464
        f->rptr = f->buffer + (f->rptr - f->end);
465
}
466

  
467 444
/* media file input */
468 445
AVInputFormat *av_find_input_format(const char *short_name);
469 446
AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened);
libavformat/dvenc.c
29 29
#include "avformat.h"
30 30
#include "dvdata.h"
31 31
#include "dv.h"
32
#include "fifo.h"
32 33

  
33 34
struct DVMuxContext {
34 35
    const DVprofile*  sys;    /* Current DV profile. E.g.: 525/60, 625/50 */
35 36
    int         n_ast;        /* Number of stereo audio streams (up to 2) */
36 37
    AVStream   *ast[2];       /* Stereo audio streams */
37
    FifoBuffer  audio_data[2]; /* Fifo for storing excessive amounts of PCM */
38
    AVFifoBuffer  audio_data[2]; /* Fifo for storing excessive amounts of PCM */
38 39
    int         frames;       /* Number of a current frame */
39 40
    time_t      start_time;   /* Start time of recording */
40 41
    int         has_audio;    /* frame under contruction has audio */
......
185 186
             if (of*2 >= size)
186 187
                 continue;
187 188

  
188
             frame_ptr[d] = fifo_peek(&c->audio_data[channel], of*2+1); // FIXME: may be we have to admit
189
             frame_ptr[d+1] = fifo_peek(&c->audio_data[channel], of*2); //        that DV is a big endian PCM
189
             frame_ptr[d] = av_fifo_peek(&c->audio_data[channel], of*2+1); // FIXME: may be we have to admit
190
             frame_ptr[d+1] = av_fifo_peek(&c->audio_data[channel], of*2); //        that DV is a big endian PCM
190 191
          }
191 192
          frame_ptr += 16 * 80; /* 15 Video DIFs + 1 Audio DIF */
192 193
       }
......
247 248
          for (i = 0; i < c->n_ast && st != c->ast[i]; i++);
248 249

  
249 250
          /* FIXME: we have to have more sensible approach than this one */
250
          if (fifo_size(&c->audio_data[i], c->audio_data[i].rptr) + data_size >= 100*AVCODEC_MAX_AUDIO_FRAME_SIZE)
251
          if (av_fifo_size(&c->audio_data[i]) + data_size >= 100*AVCODEC_MAX_AUDIO_FRAME_SIZE)
251 252
              av_log(st->codec, AV_LOG_ERROR, "Can't process DV frame #%d. Insufficient video data or severe sync problem.\n", c->frames);
252
          fifo_write(&c->audio_data[i], data, data_size, &c->audio_data[i].wptr);
253
          av_fifo_write(&c->audio_data[i], data, data_size);
253 254

  
254 255
          /* Lets see if we've got enough audio for one DV frame */
255
          c->has_audio |= ((reqasize <= fifo_size(&c->audio_data[i], c->audio_data[i].rptr)) << i);
256
          c->has_audio |= ((reqasize <= av_fifo_size(&c->audio_data[i])) << i);
256 257

  
257 258
          break;
258 259
    default:
......
264 265
        dv_inject_metadata(c, *frame);
265 266
        for (i=0; i<c->n_ast; i++) {
266 267
             dv_inject_audio(c, i, *frame);
267
             fifo_drain(&c->audio_data[i], reqasize);
268
             av_fifo_drain(&c->audio_data[i], reqasize);
268 269
        }
269 270

  
270 271
        c->has_video = 0;
......
333 334
    c->start_time = (time_t)s->timestamp;
334 335

  
335 336
    for (i=0; i<c->n_ast; i++) {
336
        if (c->ast[i] && fifo_init(&c->audio_data[i], 100*AVCODEC_MAX_AUDIO_FRAME_SIZE) < 0) {
337
        if (c->ast[i] && av_fifo_init(&c->audio_data[i], 100*AVCODEC_MAX_AUDIO_FRAME_SIZE) < 0) {
337 338
            while (i>0) {
338 339
                i--;
339
                fifo_free(&c->audio_data[i]);
340
                av_fifo_free(&c->audio_data[i]);
340 341
            }
341 342
            goto bail_out;
342 343
        }
......
353 354
{
354 355
    int i;
355 356
    for (i=0; i < c->n_ast; i++)
356
        fifo_free(&c->audio_data[i]);
357
        av_fifo_free(&c->audio_data[i]);
357 358
}
358 359

  
359 360
#ifdef CONFIG_MUXERS
libavformat/gxfenc.c
20 20
#include "avformat.h"
21 21
#include "gxf.h"
22 22
#include "riff.h"
23
#include "fifo.h"
23 24

  
24 25
#define GXF_AUDIO_PACKET_SIZE 65536
25 26

  
26 27
typedef struct GXFStreamContext {
27 28
    AVCodecContext *codec;
28
    FifoBuffer audio_buffer;
29
    AVFifoBuffer audio_buffer;
29 30
    uint32_t track_type;
30 31
    uint32_t sample_size;
31 32
    uint32_t sample_rate;
......
604 605
            sc->fields = -2;
605 606
            gxf->audio_tracks++;
606 607
            gxf->flags |= 0x04000000; /* audio is 16 bit pcm */
607
            fifo_init(&sc->audio_buffer, 3*GXF_AUDIO_PACKET_SIZE);
608
            av_fifo_init(&sc->audio_buffer, 3*GXF_AUDIO_PACKET_SIZE);
608 609
        } else if (sc->codec->codec_type == CODEC_TYPE_VIDEO) {
609 610
            /* FIXME check from time_base ? */
610 611
            if (sc->codec->height == 480 || sc->codec->height == 512) { /* NTSC or NTSC+VBI */
......
670 671

  
671 672
    for (i = 0; i < s->nb_streams; ++i) {
672 673
        if (s->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO) {
673
            fifo_free(&gxf->streams[i].audio_buffer);
674
            av_fifo_free(&gxf->streams[i].audio_buffer);
674 675
        }
675 676
        if (s->streams[i]->codec->frame_number > gxf->nb_frames)
676 677
            gxf->nb_frames = 2 * s->streams[i]->codec->frame_number;
......
762 763

  
763 764
static int gxf_new_audio_packet(GXFContext *gxf, GXFStreamContext *sc, AVPacket *pkt, int flush)
764 765
{
765
    int size = flush ? fifo_size(&sc->audio_buffer, NULL) : GXF_AUDIO_PACKET_SIZE;
766
    int size = flush ? av_fifo_size(&sc->audio_buffer) : GXF_AUDIO_PACKET_SIZE;
766 767

  
767 768
    if (!size)
768 769
        return 0;
769 770
    av_new_packet(pkt, size);
770
    fifo_read(&sc->audio_buffer, pkt->data, size, NULL);
771
    av_fifo_read(&sc->audio_buffer, pkt->data, size);
771 772
    pkt->stream_index = sc->index;
772 773
    pkt->dts = sc->current_dts;
773 774
    sc->current_dts += size / 2; /* we only support 16 bit pcm mono for now */
......
784 785
        if (s->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO) {
785 786
            GXFStreamContext *sc = &gxf->streams[i];
786 787
            if (pkt && pkt->stream_index == i) {
787
                fifo_write(&sc->audio_buffer, pkt->data, pkt->size, NULL);
788
                av_fifo_write(&sc->audio_buffer, pkt->data, pkt->size);
788 789
                pkt = NULL;
789 790
            }
790
            if (flush || fifo_size(&sc->audio_buffer, NULL) >= GXF_AUDIO_PACKET_SIZE) {
791
            if (flush || av_fifo_size(&sc->audio_buffer) >= GXF_AUDIO_PACKET_SIZE) {
791 792
                if (gxf_new_audio_packet(gxf, sc, &new_pkt, flush) > 0) {
792 793
                    pkt = &new_pkt;
793 794
                    break; /* add pkt right now into list */
libavformat/mpeg.c
18 18
 */
19 19
#include "avformat.h"
20 20
#include "bitstream.h"
21
#include "fifo.h"
21 22

  
22 23
#define MAX_PAYLOAD_SIZE 4096
23 24
//#define DEBUG_SEEK
......
35 36
} PacketDesc;
36 37

  
37 38
typedef struct {
38
    FifoBuffer fifo;
39
    AVFifoBuffer fifo;
39 40
    uint8_t id;
40 41
    int max_buffer_size; /* in bytes */
41 42
    int buffer_index;
......
45 46
    int packet_number;
46 47
    uint8_t lpcm_header[3];
47 48
    int lpcm_align;
48
    uint8_t *fifo_iframe_ptr;
49
    int bytes_to_iframe;
49 50
    int align_iframe;
50 51
    int64_t vobu_start_pts;
51 52
} StreamInfo;
......
412 413
        default:
413 414
            return -1;
414 415
        }
415
        fifo_init(&stream->fifo, 16);
416
        av_fifo_init(&stream->fifo, 16);
416 417
    }
417 418
    bitrate = 0;
418 419
    audio_bitrate = 0;
......
708 709
            }
709 710
        } else if (s->is_dvd) {
710 711
            if (stream->align_iframe || s->packet_number == 0){
711
                int bytes_to_iframe;
712
                int PES_bytes_to_fill;
713
                if (stream->fifo_iframe_ptr >= stream->fifo.rptr) {
714
                    bytes_to_iframe = stream->fifo_iframe_ptr - stream->fifo.rptr;
715
                } else {
716
                    bytes_to_iframe = (stream->fifo.end - stream->fifo.rptr) + (stream->fifo_iframe_ptr - stream->fifo.buffer);
717
                }
718
                PES_bytes_to_fill = s->packet_size - size - 10;
712
                int PES_bytes_to_fill = s->packet_size - size - 10;
719 713

  
720 714
                if (pts != AV_NOPTS_VALUE) {
721 715
                    if (dts != pts)
......
724 718
                        PES_bytes_to_fill -= 5;
725 719
                }
726 720

  
727
                if (bytes_to_iframe == 0 || s->packet_number == 0) {
721
                if (stream->bytes_to_iframe == 0 || s->packet_number == 0) {
728 722
                    size = put_system_header(ctx, buf_ptr, 0);
729 723
                    buf_ptr += size;
730 724
                    size = buf_ptr - buffer;
......
751 745
                    s->last_scr= scr;
752 746
                    buf_ptr += size;
753 747
                    /* GOP Start */
754
                } else if (bytes_to_iframe < PES_bytes_to_fill) {
755
                    pad_packet_bytes = PES_bytes_to_fill - bytes_to_iframe;
748
                } else if (stream->bytes_to_iframe < PES_bytes_to_fill) {
749
                    pad_packet_bytes = PES_bytes_to_fill - stream->bytes_to_iframe;
756 750
                }
757 751
            }
758 752
        } else {
......
824 818
            startcode = 0x100 + id;
825 819
        }
826 820

  
827
        stuffing_size = payload_size - fifo_size(&stream->fifo, stream->fifo.rptr);
821
        stuffing_size = payload_size - av_fifo_size(&stream->fifo);
828 822

  
829 823
        // first byte doesnt fit -> reset pts/dts + stuffing
830 824
        if(payload_size <= trailer_size && pts != AV_NOPTS_VALUE){
......
951 945
        }
952 946

  
953 947
        /* output data */
954
        if(put_fifo(&ctx->pb, &stream->fifo, payload_size - stuffing_size, &stream->fifo.rptr) < 0)
948
        if(av_fifo_generic_read(&stream->fifo, payload_size - stuffing_size, &put_buffer, &ctx->pb) < 0)
955 949
            return -1;
950
        stream->bytes_to_iframe -= payload_size - stuffing_size;
956 951
    }else{
957 952
        payload_size=
958 953
        stuffing_size= 0;
......
1065 1060
    for(i=0; i<ctx->nb_streams; i++){
1066 1061
        AVStream *st = ctx->streams[i];
1067 1062
        StreamInfo *stream = st->priv_data;
1068
        const int avail_data=  fifo_size(&stream->fifo, stream->fifo.rptr);
1063
        const int avail_data=  av_fifo_size(&stream->fifo);
1069 1064
        const int space= stream->max_buffer_size - stream->buffer_index;
1070 1065
        int rel_space= 1024*space / stream->max_buffer_size;
1071 1066
        PacketDesc *next_pkt= stream->premux_packet;
......
1125 1120
    st = ctx->streams[best_i];
1126 1121
    stream = st->priv_data;
1127 1122

  
1128
    assert(fifo_size(&stream->fifo, stream->fifo.rptr) > 0);
1123
    assert(av_fifo_size(&stream->fifo) > 0);
1129 1124

  
1130 1125
    assert(avail_space >= s->packet_size || ignore_constraints);
1131 1126

  
......
1141 1136
//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);
1142 1137
        es_size= flush_packet(ctx, best_i, timestamp_packet->pts, timestamp_packet->dts, scr, trailer_size);
1143 1138
    }else{
1144
        assert(fifo_size(&stream->fifo, stream->fifo.rptr) == trailer_size);
1139
        assert(av_fifo_size(&stream->fifo) == trailer_size);
1145 1140
        es_size= flush_packet(ctx, best_i, AV_NOPTS_VALUE, AV_NOPTS_VALUE, scr, trailer_size);
1146 1141
    }
1147 1142

  
......
1204 1199
        stream->predecode_packet= pkt_desc;
1205 1200
    stream->next_packet= &pkt_desc->next;
1206 1201

  
1207
    fifo_realloc(&stream->fifo, fifo_size(&stream->fifo, NULL) + size + 1);
1202
    av_fifo_realloc(&stream->fifo, av_fifo_size(&stream->fifo) + size + 1);
1208 1203

  
1209 1204
    if (s->is_dvd){
1210 1205
        if (is_iframe && (s->packet_number == 0 || (pts - stream->vobu_start_pts >= 36000))) { // min VOBU length 0.4 seconds (mpucoder)
1211
            stream->fifo_iframe_ptr = stream->fifo.wptr;
1206
            stream->bytes_to_iframe = av_fifo_size(&stream->fifo);
1212 1207
            stream->align_iframe = 1;
1213 1208
            stream->vobu_start_pts = pts;
1214 1209
        } else {
......
1216 1211
        }
1217 1212
    }
1218 1213

  
1219
    fifo_write(&stream->fifo, buf, size, &stream->fifo.wptr);
1214
    av_fifo_write(&stream->fifo, buf, size);
1220 1215

  
1221 1216
    for(;;){
1222 1217
        int ret= output_packet(ctx, 0);
......
1248 1243
    for(i=0;i<ctx->nb_streams;i++) {
1249 1244
        stream = ctx->streams[i]->priv_data;
1250 1245

  
1251
        assert(fifo_size(&stream->fifo, stream->fifo.rptr) == 0);
1252
        fifo_free(&stream->fifo);
1246
        assert(av_fifo_size(&stream->fifo) == 0);
1247
        av_fifo_free(&stream->fifo);
1253 1248
    }
1254 1249
    return 0;
1255 1250
}
libavformat/utils.c
263 263
    return 0;
264 264
}
265 265

  
266
/* fifo handling */
267

  
268
int fifo_init(FifoBuffer *f, int size)
269
{
270
    f->buffer = av_malloc(size);
271
    if (!f->buffer)
272
        return -1;
273
    f->end = f->buffer + size;
274
    f->wptr = f->rptr = f->buffer;
275
    return 0;
276
}
277

  
278
void fifo_free(FifoBuffer *f)
279
{
280
    av_free(f->buffer);
281
}
282

  
283
int fifo_size(FifoBuffer *f, uint8_t *rptr)
284
{
285
    int size;
286

  
287
    if(!rptr)
288
        rptr= f->rptr;
289

  
290
    if (f->wptr >= rptr) {
291
        size = f->wptr - rptr;
292
    } else {
293
        size = (f->end - rptr) + (f->wptr - f->buffer);
294
    }
295
    return size;
296
}
297

  
298
/**
299
 * Get data from the fifo (returns -1 if not enough data).
300
 */
301
int fifo_read(FifoBuffer *f, uint8_t *buf, int buf_size, uint8_t **rptr_ptr)
302
{
303
    uint8_t *rptr;
304
    int size, len;
305

  
306
    if(!rptr_ptr)
307
        rptr_ptr= &f->rptr;
308
    rptr = *rptr_ptr;
309

  
310
    if (f->wptr >= rptr) {
311
        size = f->wptr - rptr;
312
    } else {
313
        size = (f->end - rptr) + (f->wptr - f->buffer);
314
    }
315

  
316
    if (size < buf_size)
317
        return -1;
318
    while (buf_size > 0) {
319
        len = f->end - rptr;
320
        if (len > buf_size)
321
            len = buf_size;
322
        memcpy(buf, rptr, len);
323
        buf += len;
324
        rptr += len;
325
        if (rptr >= f->end)
326
            rptr = f->buffer;
327
        buf_size -= len;
328
    }
329
    *rptr_ptr = rptr;
330
    return 0;
331
}
332

  
333
/**
334
 * Resizes a FIFO.
335
 */
336
void fifo_realloc(FifoBuffer *f, unsigned int new_size){
337
    unsigned int old_size= f->end - f->buffer;
338

  
339
    if(old_size < new_size){
340
        uint8_t *old= f->buffer;
341

  
342
        f->buffer= av_realloc(f->buffer, new_size);
343

  
344
        f->rptr += f->buffer - old;
345
        f->wptr += f->buffer - old;
346

  
347
        if(f->wptr < f->rptr){
348
            memmove(f->rptr + new_size - old_size, f->rptr, f->buffer + old_size - f->rptr);
349
            f->rptr += new_size - old_size;
350
        }
351
        f->end= f->buffer + new_size;
352
    }
353
}
354

  
355
void fifo_write(FifoBuffer *f, const uint8_t *buf, int size, uint8_t **wptr_ptr)
356
{
357
    int len;
358
    uint8_t *wptr;
359

  
360
    if(!wptr_ptr)
361
        wptr_ptr= &f->wptr;
362
    wptr = *wptr_ptr;
363

  
364
    while (size > 0) {
365
        len = f->end - wptr;
366
        if (len > size)
367
            len = size;
368
        memcpy(wptr, buf, len);
369
        wptr += len;
370
        if (wptr >= f->end)
371
            wptr = f->buffer;
372
        buf += len;
373
        size -= len;
374
    }
375
    *wptr_ptr = wptr;
376
}
377

  
378
/* get data from the fifo (return -1 if not enough data) */
379
int put_fifo(ByteIOContext *pb, FifoBuffer *f, int buf_size, uint8_t **rptr_ptr)
380
{
381
    uint8_t *rptr = *rptr_ptr;
382
    int size, len;
383

  
384
    if (f->wptr >= rptr) {
385
        size = f->wptr - rptr;
386
    } else {
387
        size = (f->end - rptr) + (f->wptr - f->buffer);
388
    }
389

  
390
    if (size < buf_size)
391
        return -1;
392
    while (buf_size > 0) {
393
        len = f->end - rptr;
394
        if (len > buf_size)
395
            len = buf_size;
396
        put_buffer(pb, rptr, len);
397
        rptr += len;
398
        if (rptr >= f->end)
399
            rptr = f->buffer;
400
        buf_size -= len;
401
    }
402
    *rptr_ptr = rptr;
403
    return 0;
404
}
405

  
406 266
/**
407 267
 * Allocate the payload of a packet and intialized its fields to default values.
408 268
 *
libavutil/Makefile
16 16
      adler32.o \
17 17
      log.o \
18 18
      mem.o \
19
      fifo.o \
19 20

  
20 21
HEADERS = avutil.h common.h mathematics.h integer.h rational.h \
21
          intfloat_readwrite.h md5.h adler32.h log.h
22
          intfloat_readwrite.h md5.h adler32.h log.h fifo.h
22 23

  
23 24
NAME=avutil
24 25
ifeq ($(BUILD_SHARED),yes)
libavutil/fifo.c
1
/*
2
 * A very simple circular buffer FIFO implementation
3
 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
4
 * Copyright (c) 2006 Roman Shaposhnik
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
 */
20
#include "common.h"
21
#include "fifo.h"
22

  
23
int av_fifo_init(AVFifoBuffer *f, int size)
24
{
25
    f->buffer = av_malloc(size);
26
    if (!f->buffer)
27
        return -1;
28
    f->end = f->buffer + size;
29
    f->wptr = f->rptr = f->buffer;
30
    return 0;
31
}
32

  
33
void av_fifo_free(AVFifoBuffer *f)
34
{
35
    av_free(f->buffer);
36
}
37

  
38
int av_fifo_size(AVFifoBuffer *f)
39
{
40
    int size = f->wptr - f->rptr;
41
    if (size < 0)
42
        size += f->end - f->buffer;
43
    return size;
44
}
45

  
46
/**
47
 * Get data from the fifo (returns -1 if not enough data).
48
 */
49
int av_fifo_read(AVFifoBuffer *f, uint8_t *buf, int buf_size)
50
{
51
    int len;
52
    int size = f->wptr - f->rptr;
53
    if (size < 0)
54
        size += f->end - f->buffer;
55

  
56
    if (size < buf_size)
57
        return -1;
58
    while (buf_size > 0) {
59
        len = FFMIN(f->end - f->rptr, buf_size);
60
        memcpy(buf, f->rptr, len);
61
        buf += len;
62
        f->rptr += len;
63
        if (f->rptr >= f->end)
64
            f->rptr = f->buffer;
65
        buf_size -= len;
66
    }
67
    return 0;
68
}
69

  
70
/**
71
 * Resizes a FIFO.
72
 */
73
void av_fifo_realloc(AVFifoBuffer *f, unsigned int new_size) {
74
    unsigned int old_size= f->end - f->buffer;
75

  
76
    if(old_size < new_size){
77
        uint8_t *old= f->buffer;
78

  
79
        f->buffer= av_realloc(f->buffer, new_size);
80

  
81
        f->rptr += f->buffer - old;
82
        f->wptr += f->buffer - old;
83

  
84
        if(f->wptr < f->rptr){
85
            memmove(f->rptr + new_size - old_size, f->rptr, f->buffer + old_size - f->rptr);
86
            f->rptr += new_size - old_size;
87
        }
88
        f->end= f->buffer + new_size;
89
    }
90
}
91

  
92
void av_fifo_write(AVFifoBuffer *f, const uint8_t *buf, int size)
93
{
94
    int len;
95

  
96
    while (size > 0) {
97
        len = FFMIN(f->end - f->wptr, size);
98
        memcpy(f->wptr, buf, len);
99
        f->wptr += len;
100
        if (f->wptr >= f->end)
101
            f->wptr = f->buffer;
102
        buf += len;
103
        size -= len;
104
    }
105
}
106

  
107

  
108
/* get data from the fifo (return -1 if not enough data) */
109
int av_fifo_generic_read(AVFifoBuffer *f, int buf_size, void (*func)(void*, void*, int), void* dest)
110
{
111
    int len;
112
    int size = f->wptr - f->rptr;
113
    if (size < 0)
114
        size += f->end - f->buffer;
115

  
116
    if (size < buf_size)
117
        return -1;
118
    while (buf_size > 0) {
119
        len = FFMIN(f->end - f->rptr, buf_size);
120
        func(dest, f->rptr, len);
121
        f->rptr += len;
122
        if (f->rptr >= f->end)
123
            f->rptr = f->buffer;
124
        buf_size -= len;
125
    }
126
    return 0;
127
}
128

  
129
/* discard data from the fifo */
130
void av_fifo_drain(AVFifoBuffer *f, int size)
131
{
132
    f->rptr += size;
133
    if (f->rptr >= f->end)
134
        f->rptr -= f->end - f->buffer;
135
}
libavutil/fifo.h
1
#ifndef FIFO_H
2
#define FIFO_H
3

  
4
typedef struct AVFifoBuffer {
5
    uint8_t *buffer;
6
    uint8_t *rptr, *wptr, *end;
7
} AVFifoBuffer;
8

  
9
int av_fifo_init(AVFifoBuffer *f, int size);
10
void av_fifo_free(AVFifoBuffer *f);
11
int av_fifo_size(AVFifoBuffer *f);
12
int av_fifo_read(AVFifoBuffer *f, uint8_t *buf, int buf_size);
13
int av_fifo_generic_read(AVFifoBuffer *f, int buf_size, void (*func)(void*, void*, int), void* dest);
14
void av_fifo_write(AVFifoBuffer *f, const uint8_t *buf, int size);
15
void av_fifo_realloc(AVFifoBuffer *f, unsigned int size);
16
void av_fifo_drain(AVFifoBuffer *f, int size);
17

  
18
static inline uint8_t av_fifo_peek(AVFifoBuffer *f, int offs)
19
{
20
    uint8_t *ptr = f->rptr + offs;
21
    if (ptr >= f->end)
22
        ptr -= f->end - f->buffer;
23
    return *ptr;
24
}
25
#endif /* FIFO_H */

Also available in: Unified diff