libavformat/utils.c into libavutil Originally committed as revision 6310 to svn://svn.ffmpeg.org/ffmpeg/trunktags/v0.5
| @@ -23,6 +23,7 @@ | |||||
| #include "framehook.h" | #include "framehook.h" | ||||
| #include "dsputil.h" | #include "dsputil.h" | ||||
| #include "opt.h" | #include "opt.h" | ||||
| #include "fifo.h" | |||||
| #ifndef __MINGW32__ | #ifndef __MINGW32__ | ||||
| #include <unistd.h> | #include <unistd.h> | ||||
| @@ -267,7 +268,7 @@ typedef struct AVOutputStream { | |||||
| /* audio only */ | /* audio only */ | ||||
| int audio_resample; | int audio_resample; | ||||
| ReSampleContext *resample; /* for audio resampling */ | 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; | FILE *logfile; | ||||
| } AVOutputStream; | } AVOutputStream; | ||||
| @@ -471,7 +472,7 @@ static void do_audio_out(AVFormatContext *s, | |||||
| if(audio_sync_method){ | if(audio_sync_method){ | ||||
| double delta = get_sync_ipts(ost) * enc->sample_rate - ost->sync_opts | 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; | double idelta= delta*ist->st->codec->sample_rate / enc->sample_rate; | ||||
| int byte_delta= ((int)idelta)*2*ist->st->codec->channels; | 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); | assert(ost->audio_resample); | ||||
| if(verbose > 2) | if(verbose > 2) | ||||
| fprintf(stderr, "compensating audio timestamp drift:%f compensation:%d in:%d\n", delta, comp, enc->sample_rate); | 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); | av_resample_compensate(*(struct AVResampleContext**)ost->resample, comp, enc->sample_rate); | ||||
| } | } | ||||
| } | } | ||||
| }else | }else | ||||
| ost->sync_opts= lrintf(get_sync_ipts(ost) * enc->sample_rate) | 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) { | if (ost->audio_resample) { | ||||
| buftmp = audio_buf; | buftmp = audio_buf; | ||||
| @@ -530,13 +531,11 @@ static void do_audio_out(AVFormatContext *s, | |||||
| /* now encode as many frames as possible */ | /* now encode as many frames as possible */ | ||||
| if (enc->frame_size > 1) { | if (enc->frame_size > 1) { | ||||
| /* output resampled raw samples */ | /* 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; | 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; | AVPacket pkt; | ||||
| av_init_packet(&pkt); | av_init_packet(&pkt); | ||||
| @@ -1317,14 +1316,13 @@ static int output_packet(AVInputStream *ist, int ist_index, | |||||
| switch(ost->st->codec->codec_type) { | switch(ost->st->codec->codec_type) { | ||||
| case CODEC_TYPE_AUDIO: | case CODEC_TYPE_AUDIO: | ||||
| fifo_bytes = fifo_size(&ost->fifo, NULL); | |||||
| fifo_bytes = av_fifo_size(&ost->fifo); | |||||
| ret = 0; | ret = 0; | ||||
| /* encode any samples remaining in fifo */ | /* encode any samples remaining in fifo */ | ||||
| if(fifo_bytes > 0 && enc->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) { | if(fifo_bytes > 0 && enc->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) { | ||||
| int fs_tmp = enc->frame_size; | int fs_tmp = enc->frame_size; | ||||
| enc->frame_size = fifo_bytes / (2 * enc->channels); | 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); | ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, samples); | ||||
| } | } | ||||
| enc->frame_size = fs_tmp; | enc->frame_size = fs_tmp; | ||||
| @@ -1563,7 +1561,7 @@ static int av_encode(AVFormatContext **output_files, | |||||
| } else { | } else { | ||||
| switch(codec->codec_type) { | switch(codec->codec_type) { | ||||
| case CODEC_TYPE_AUDIO: | 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; | goto fail; | ||||
| if (codec->channels == icodec->channels && | if (codec->channels == icodec->channels && | ||||
| @@ -2018,8 +2016,8 @@ static int av_encode(AVFormatContext **output_files, | |||||
| fclose(ost->logfile); | fclose(ost->logfile); | ||||
| ost->logfile = NULL; | 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]); | av_free(ost->pict_tmp.data[0]); | ||||
| if (ost->video_resample) | if (ost->video_resample) | ||||
| sws_freeContext(ost->img_resample_ctx); | sws_freeContext(ost->img_resample_ctx); | ||||
| @@ -441,29 +441,6 @@ void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload); | |||||
| void av_register_all(void); | 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 */ | /* media file input */ | ||||
| AVInputFormat *av_find_input_format(const char *short_name); | AVInputFormat *av_find_input_format(const char *short_name); | ||||
| AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened); | AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened); | ||||
| @@ -29,12 +29,13 @@ | |||||
| #include "avformat.h" | #include "avformat.h" | ||||
| #include "dvdata.h" | #include "dvdata.h" | ||||
| #include "dv.h" | #include "dv.h" | ||||
| #include "fifo.h" | |||||
| struct DVMuxContext { | struct DVMuxContext { | ||||
| const DVprofile* sys; /* Current DV profile. E.g.: 525/60, 625/50 */ | const DVprofile* sys; /* Current DV profile. E.g.: 525/60, 625/50 */ | ||||
| int n_ast; /* Number of stereo audio streams (up to 2) */ | int n_ast; /* Number of stereo audio streams (up to 2) */ | ||||
| AVStream *ast[2]; /* Stereo audio streams */ | 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 */ | int frames; /* Number of a current frame */ | ||||
| time_t start_time; /* Start time of recording */ | time_t start_time; /* Start time of recording */ | ||||
| int has_audio; /* frame under contruction has audio */ | 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) | if (of*2 >= size) | ||||
| continue; | 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 */ | 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++); | for (i = 0; i < c->n_ast && st != c->ast[i]; i++); | ||||
| /* FIXME: we have to have more sensible approach than this one */ | /* 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); | 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 */ | /* 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; | break; | ||||
| default: | default: | ||||
| @@ -264,7 +265,7 @@ int dv_assemble_frame(DVMuxContext *c, AVStream* st, | |||||
| dv_inject_metadata(c, *frame); | dv_inject_metadata(c, *frame); | ||||
| for (i=0; i<c->n_ast; i++) { | for (i=0; i<c->n_ast; i++) { | ||||
| dv_inject_audio(c, i, *frame); | 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; | c->has_video = 0; | ||||
| @@ -333,10 +334,10 @@ DVMuxContext* dv_init_mux(AVFormatContext* s) | |||||
| c->start_time = (time_t)s->timestamp; | c->start_time = (time_t)s->timestamp; | ||||
| for (i=0; i<c->n_ast; i++) { | 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) { | while (i>0) { | ||||
| i--; | i--; | ||||
| fifo_free(&c->audio_data[i]); | |||||
| av_fifo_free(&c->audio_data[i]); | |||||
| } | } | ||||
| goto bail_out; | goto bail_out; | ||||
| } | } | ||||
| @@ -353,7 +354,7 @@ void dv_delete_mux(DVMuxContext *c) | |||||
| { | { | ||||
| int i; | int i; | ||||
| for (i=0; i < c->n_ast; 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 | #ifdef CONFIG_MUXERS | ||||
| @@ -20,12 +20,13 @@ | |||||
| #include "avformat.h" | #include "avformat.h" | ||||
| #include "gxf.h" | #include "gxf.h" | ||||
| #include "riff.h" | #include "riff.h" | ||||
| #include "fifo.h" | |||||
| #define GXF_AUDIO_PACKET_SIZE 65536 | #define GXF_AUDIO_PACKET_SIZE 65536 | ||||
| typedef struct GXFStreamContext { | typedef struct GXFStreamContext { | ||||
| AVCodecContext *codec; | AVCodecContext *codec; | ||||
| FifoBuffer audio_buffer; | |||||
| AVFifoBuffer audio_buffer; | |||||
| uint32_t track_type; | uint32_t track_type; | ||||
| uint32_t sample_size; | uint32_t sample_size; | ||||
| uint32_t sample_rate; | uint32_t sample_rate; | ||||
| @@ -604,7 +605,7 @@ static int gxf_write_header(AVFormatContext *s) | |||||
| sc->fields = -2; | sc->fields = -2; | ||||
| gxf->audio_tracks++; | gxf->audio_tracks++; | ||||
| gxf->flags |= 0x04000000; /* audio is 16 bit pcm */ | 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) { | } else if (sc->codec->codec_type == CODEC_TYPE_VIDEO) { | ||||
| /* FIXME check from time_base ? */ | /* FIXME check from time_base ? */ | ||||
| if (sc->codec->height == 480 || sc->codec->height == 512) { /* NTSC or NTSC+VBI */ | 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) { | for (i = 0; i < s->nb_streams; ++i) { | ||||
| if (s->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO) { | 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) | if (s->streams[i]->codec->frame_number > gxf->nb_frames) | ||||
| gxf->nb_frames = 2 * s->streams[i]->codec->frame_number; | 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) | 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) | if (!size) | ||||
| return 0; | return 0; | ||||
| av_new_packet(pkt, size); | 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->stream_index = sc->index; | ||||
| pkt->dts = sc->current_dts; | pkt->dts = sc->current_dts; | ||||
| sc->current_dts += size / 2; /* we only support 16 bit pcm mono for now */ | 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) { | if (s->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO) { | ||||
| GXFStreamContext *sc = &gxf->streams[i]; | GXFStreamContext *sc = &gxf->streams[i]; | ||||
| if (pkt && pkt->stream_index == 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; | 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) { | if (gxf_new_audio_packet(gxf, sc, &new_pkt, flush) > 0) { | ||||
| pkt = &new_pkt; | pkt = &new_pkt; | ||||
| break; /* add pkt right now into list */ | break; /* add pkt right now into list */ | ||||
| @@ -18,6 +18,7 @@ | |||||
| */ | */ | ||||
| #include "avformat.h" | #include "avformat.h" | ||||
| #include "bitstream.h" | #include "bitstream.h" | ||||
| #include "fifo.h" | |||||
| #define MAX_PAYLOAD_SIZE 4096 | #define MAX_PAYLOAD_SIZE 4096 | ||||
| //#define DEBUG_SEEK | //#define DEBUG_SEEK | ||||
| @@ -35,7 +36,7 @@ typedef struct PacketDesc { | |||||
| } PacketDesc; | } PacketDesc; | ||||
| typedef struct { | typedef struct { | ||||
| FifoBuffer fifo; | |||||
| AVFifoBuffer fifo; | |||||
| uint8_t id; | uint8_t id; | ||||
| int max_buffer_size; /* in bytes */ | int max_buffer_size; /* in bytes */ | ||||
| int buffer_index; | int buffer_index; | ||||
| @@ -45,7 +46,7 @@ typedef struct { | |||||
| int packet_number; | int packet_number; | ||||
| uint8_t lpcm_header[3]; | uint8_t lpcm_header[3]; | ||||
| int lpcm_align; | int lpcm_align; | ||||
| uint8_t *fifo_iframe_ptr; | |||||
| int bytes_to_iframe; | |||||
| int align_iframe; | int align_iframe; | ||||
| int64_t vobu_start_pts; | int64_t vobu_start_pts; | ||||
| } StreamInfo; | } StreamInfo; | ||||
| @@ -412,7 +413,7 @@ static int mpeg_mux_init(AVFormatContext *ctx) | |||||
| default: | default: | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| fifo_init(&stream->fifo, 16); | |||||
| av_fifo_init(&stream->fifo, 16); | |||||
| } | } | ||||
| bitrate = 0; | bitrate = 0; | ||||
| audio_bitrate = 0; | audio_bitrate = 0; | ||||
| @@ -708,14 +709,7 @@ static int flush_packet(AVFormatContext *ctx, int stream_index, | |||||
| } | } | ||||
| } else if (s->is_dvd) { | } else if (s->is_dvd) { | ||||
| if (stream->align_iframe || s->packet_number == 0){ | 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 (pts != AV_NOPTS_VALUE) { | ||||
| if (dts != pts) | if (dts != pts) | ||||
| @@ -724,7 +718,7 @@ static int flush_packet(AVFormatContext *ctx, int stream_index, | |||||
| PES_bytes_to_fill -= 5; | 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); | size = put_system_header(ctx, buf_ptr, 0); | ||||
| buf_ptr += size; | buf_ptr += size; | ||||
| size = buf_ptr - buffer; | size = buf_ptr - buffer; | ||||
| @@ -751,8 +745,8 @@ static int flush_packet(AVFormatContext *ctx, int stream_index, | |||||
| s->last_scr= scr; | s->last_scr= scr; | ||||
| buf_ptr += size; | buf_ptr += size; | ||||
| /* GOP Start */ | /* 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 { | } else { | ||||
| @@ -824,7 +818,7 @@ static int flush_packet(AVFormatContext *ctx, int stream_index, | |||||
| startcode = 0x100 + id; | 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 | // first byte doesnt fit -> reset pts/dts + stuffing | ||||
| if(payload_size <= trailer_size && pts != AV_NOPTS_VALUE){ | if(payload_size <= trailer_size && pts != AV_NOPTS_VALUE){ | ||||
| @@ -951,8 +945,9 @@ static int flush_packet(AVFormatContext *ctx, int stream_index, | |||||
| } | } | ||||
| /* output data */ | /* 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; | return -1; | ||||
| stream->bytes_to_iframe -= payload_size - stuffing_size; | |||||
| }else{ | }else{ | ||||
| payload_size= | payload_size= | ||||
| stuffing_size= 0; | stuffing_size= 0; | ||||
| @@ -1065,7 +1060,7 @@ retry: | |||||
| for(i=0; i<ctx->nb_streams; i++){ | for(i=0; i<ctx->nb_streams; i++){ | ||||
| AVStream *st = ctx->streams[i]; | AVStream *st = ctx->streams[i]; | ||||
| StreamInfo *stream = st->priv_data; | 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; | const int space= stream->max_buffer_size - stream->buffer_index; | ||||
| int rel_space= 1024*space / stream->max_buffer_size; | int rel_space= 1024*space / stream->max_buffer_size; | ||||
| PacketDesc *next_pkt= stream->premux_packet; | PacketDesc *next_pkt= stream->premux_packet; | ||||
| @@ -1125,7 +1120,7 @@ retry: | |||||
| st = ctx->streams[best_i]; | st = ctx->streams[best_i]; | ||||
| stream = st->priv_data; | 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); | 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); | //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); | es_size= flush_packet(ctx, best_i, timestamp_packet->pts, timestamp_packet->dts, scr, trailer_size); | ||||
| }else{ | }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); | 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->predecode_packet= pkt_desc; | ||||
| stream->next_packet= &pkt_desc->next; | 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 (s->is_dvd){ | ||||
| if (is_iframe && (s->packet_number == 0 || (pts - stream->vobu_start_pts >= 36000))) { // min VOBU length 0.4 seconds (mpucoder) | 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->align_iframe = 1; | ||||
| stream->vobu_start_pts = pts; | stream->vobu_start_pts = pts; | ||||
| } else { | } 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(;;){ | for(;;){ | ||||
| int ret= output_packet(ctx, 0); | 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++) { | for(i=0;i<ctx->nb_streams;i++) { | ||||
| stream = ctx->streams[i]->priv_data; | 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; | return 0; | ||||
| } | } | ||||
| @@ -263,146 +263,6 @@ int av_dup_packet(AVPacket *pkt) | |||||
| return 0; | 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. | * Allocate the payload of a packet and intialized its fields to default values. | ||||
| * | * | ||||
| @@ -16,9 +16,10 @@ OBJS= mathematics.o \ | |||||
| adler32.o \ | adler32.o \ | ||||
| log.o \ | log.o \ | ||||
| mem.o \ | mem.o \ | ||||
| fifo.o \ | |||||
| HEADERS = avutil.h common.h mathematics.h integer.h rational.h \ | 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 | NAME=avutil | ||||
| ifeq ($(BUILD_SHARED),yes) | ifeq ($(BUILD_SHARED),yes) | ||||
| @@ -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; | |||||
| } | |||||
| @@ -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 */ | |||||