From 576ae256a404ceba6527e6042d500e04b3f489a3 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 8 Oct 2004 20:09:52 +0000 Subject: [PATCH] write error handling Originally committed as revision 3572 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavformat/avformat.h | 2 +- libavformat/avio.h | 6 ++++-- libavformat/aviobuf.c | 36 ++++++++++++++++++++++++++---------- libavformat/utils.c | 13 ++++++++++++- 4 files changed, 43 insertions(+), 14 deletions(-) diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 4994b6ac78..4cd9da59e8 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -5,7 +5,7 @@ extern "C" { #endif -#define LIBAVFORMAT_BUILD 4617 +#define LIBAVFORMAT_BUILD 4618 #define LIBAVFORMAT_VERSION_INT FFMPEG_VERSION_INT #define LIBAVFORMAT_VERSION FFMPEG_VERSION diff --git a/libavformat/avio.h b/libavformat/avio.h index 53ed22a3a1..f834ef34a7 100644 --- a/libavformat/avio.h +++ b/libavformat/avio.h @@ -70,7 +70,7 @@ typedef struct { unsigned char *buf_ptr, *buf_end; void *opaque; int (*read_packet)(void *opaque, uint8_t *buf, int buf_size); - void (*write_packet)(void *opaque, uint8_t *buf, int buf_size); + int (*write_packet)(void *opaque, uint8_t *buf, int buf_size); int (*seek)(void *opaque, offset_t offset, int whence); offset_t pos; /* position in the file of the current buffer */ int must_flush; /* true if the next seek should flush */ @@ -81,6 +81,7 @@ typedef struct { unsigned long checksum; unsigned char *checksum_ptr; unsigned long (*update_checksum)(unsigned long checksum, const uint8_t *buf, unsigned int size); + int error; ///< contains the error code or 0 if no error happened } ByteIOContext; int init_put_byte(ByteIOContext *s, @@ -89,7 +90,7 @@ int init_put_byte(ByteIOContext *s, int write_flag, void *opaque, int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), - void (*write_packet)(void *opaque, uint8_t *buf, int buf_size), + int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), int (*seek)(void *opaque, offset_t offset, int whence)); void put_byte(ByteIOContext *s, int b); @@ -109,6 +110,7 @@ offset_t url_fseek(ByteIOContext *s, offset_t offset, int whence); void url_fskip(ByteIOContext *s, offset_t offset); offset_t url_ftell(ByteIOContext *s); int url_feof(ByteIOContext *s); +int url_ferror(ByteIOContext *s); #define URL_EOF (-1) int url_fgetc(ByteIOContext *s); diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index 0ad63299a4..31c6a7fec5 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -28,7 +28,7 @@ int init_put_byte(ByteIOContext *s, int write_flag, void *opaque, int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), - void (*write_packet)(void *opaque, uint8_t *buf, int buf_size), + int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), int (*seek)(void *opaque, offset_t offset, int whence)) { s->buffer = buffer; @@ -46,6 +46,7 @@ int init_put_byte(ByteIOContext *s, s->pos = 0; s->must_flush = 0; s->eof_reached = 0; + s->error = 0; s->is_streamed = 0; s->max_packet_size = 0; s->update_checksum= NULL; @@ -57,8 +58,12 @@ int init_put_byte(ByteIOContext *s, static void flush_buffer(ByteIOContext *s) { if (s->buf_ptr > s->buffer) { - if (s->write_packet) - s->write_packet(s->opaque, s->buffer, s->buf_ptr - s->buffer); + if (s->write_packet && !s->error){ + int ret= s->write_packet(s->opaque, s->buffer, s->buf_ptr - s->buffer); + if(ret < 0){ + s->error = ret; + } + } if(s->update_checksum){ s->checksum= s->update_checksum(s->checksum, s->checksum_ptr, s->buf_ptr - s->checksum_ptr); s->checksum_ptr= s->buffer; @@ -172,6 +177,11 @@ int url_feof(ByteIOContext *s) return s->eof_reached; } +int url_ferror(ByteIOContext *s) +{ + return s->error; +} + #ifdef CONFIG_ENCODERS void put_le32(ByteIOContext *s, unsigned int val) { @@ -260,6 +270,8 @@ static void fill_buffer(ByteIOContext *s) /* do not modify buffer if EOF reached so that a seek back can be done without rereading data */ s->eof_reached = 1; + if(len<0) + s->error= len; } else { s->pos += len; s->buf_ptr = s->buffer; @@ -432,10 +444,10 @@ uint64_t get_be64(ByteIOContext *s) /* link with avio functions */ #ifdef CONFIG_ENCODERS -static void url_write_packet(void *opaque, uint8_t *buf, int buf_size) +static int url_write_packet(void *opaque, uint8_t *buf, int buf_size) { URLContext *h = opaque; - url_write(h, buf, buf_size); + return url_write(h, buf, buf_size); } #else #define url_write_packet NULL @@ -609,7 +621,7 @@ typedef struct DynBuffer { uint8_t io_buffer[1]; } DynBuffer; -static void dyn_buf_write(void *opaque, uint8_t *buf, int buf_size) +static int dyn_buf_write(void *opaque, uint8_t *buf, int buf_size) { DynBuffer *d = opaque; int new_size, new_allocated_size; @@ -627,28 +639,32 @@ static void dyn_buf_write(void *opaque, uint8_t *buf, int buf_size) if (new_allocated_size > d->allocated_size) { d->buffer = av_realloc(d->buffer, new_allocated_size); if(d->buffer == NULL) - return ; + return -1234; d->allocated_size = new_allocated_size; } memcpy(d->buffer + d->pos, buf, buf_size); d->pos = new_size; if (d->pos > d->size) d->size = d->pos; + return buf_size; } -static void dyn_packet_buf_write(void *opaque, uint8_t *buf, int buf_size) +static int dyn_packet_buf_write(void *opaque, uint8_t *buf, int buf_size) { unsigned char buf1[4]; + int ret; /* packetized write: output the header */ buf1[0] = (buf_size >> 24); buf1[1] = (buf_size >> 16); buf1[2] = (buf_size >> 8); buf1[3] = (buf_size); - dyn_buf_write(opaque, buf1, 4); + ret= dyn_buf_write(opaque, buf1, 4); + if(ret < 0) + return ret; /* then the data */ - dyn_buf_write(opaque, buf, buf_size); + return dyn_buf_write(opaque, buf, buf_size); } static int dyn_buf_seek(void *opaque, offset_t offset, int whence) diff --git a/libavformat/utils.c b/libavformat/utils.c index 7129b39b76..788f4ab2c9 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -1996,11 +1996,16 @@ static void truncate_ts(AVStream *st, AVPacket *pkt){ */ int av_write_frame(AVFormatContext *s, AVPacket *pkt) { + int ret; + compute_pkt_fields2(s->streams[pkt->stream_index], pkt); truncate_ts(s->streams[pkt->stream_index], pkt); - return s->oformat->write_packet(s, pkt); + ret= s->oformat->write_packet(s, pkt); + if(!ret) + ret= url_ferror(&s->pb); + return ret; } /** @@ -2111,6 +2116,8 @@ int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt){ if(ret<0) return ret; + if(url_ferror(&s->pb)) + return url_ferror(&s->pb); } } @@ -2139,10 +2146,14 @@ int av_write_trailer(AVFormatContext *s) if(ret<0) goto fail; + if(url_ferror(&s->pb)) + goto fail; } ret = s->oformat->write_trailer(s); fail: + if(ret == 0) + ret=url_ferror(&s->pb); for(i=0;inb_streams;i++) av_freep(&s->streams[i]->priv_data); av_freep(&s->priv_data);