Browse code

write error handling

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

Michael Niedermayer authored on 2004/10/09 05:09:52
Showing 4 changed files
... ...
@@ -5,7 +5,7 @@
5 5
 extern "C" {
6 6
 #endif
7 7
 
8
-#define LIBAVFORMAT_BUILD       4617
8
+#define LIBAVFORMAT_BUILD       4618
9 9
 
10 10
 #define LIBAVFORMAT_VERSION_INT FFMPEG_VERSION_INT
11 11
 #define LIBAVFORMAT_VERSION     FFMPEG_VERSION
... ...
@@ -70,7 +70,7 @@ typedef struct {
70 70
     unsigned char *buf_ptr, *buf_end;
71 71
     void *opaque;
72 72
     int (*read_packet)(void *opaque, uint8_t *buf, int buf_size);
73
-    void (*write_packet)(void *opaque, uint8_t *buf, int buf_size);
73
+    int (*write_packet)(void *opaque, uint8_t *buf, int buf_size);
74 74
     int (*seek)(void *opaque, offset_t offset, int whence);
75 75
     offset_t pos; /* position in the file of the current buffer */
76 76
     int must_flush; /* true if the next seek should flush */
... ...
@@ -81,6 +81,7 @@ typedef struct {
81 81
     unsigned long checksum;
82 82
     unsigned char *checksum_ptr;
83 83
     unsigned long (*update_checksum)(unsigned long checksum, const uint8_t *buf, unsigned int size);
84
+    int error;         ///< contains the error code or 0 if no error happened
84 85
 } ByteIOContext;
85 86
 
86 87
 int init_put_byte(ByteIOContext *s,
... ...
@@ -89,7 +90,7 @@ int init_put_byte(ByteIOContext *s,
89 89
                   int write_flag,
90 90
                   void *opaque,
91 91
                   int (*read_packet)(void *opaque, uint8_t *buf, int buf_size),
92
-                  void (*write_packet)(void *opaque, uint8_t *buf, int buf_size),
92
+                  int (*write_packet)(void *opaque, uint8_t *buf, int buf_size),
93 93
                   int (*seek)(void *opaque, offset_t offset, int whence));
94 94
 
95 95
 void put_byte(ByteIOContext *s, int b);
... ...
@@ -109,6 +110,7 @@ offset_t url_fseek(ByteIOContext *s, offset_t offset, int whence);
109 109
 void url_fskip(ByteIOContext *s, offset_t offset);
110 110
 offset_t url_ftell(ByteIOContext *s);
111 111
 int url_feof(ByteIOContext *s);
112
+int url_ferror(ByteIOContext *s);
112 113
 
113 114
 #define URL_EOF (-1)
114 115
 int url_fgetc(ByteIOContext *s);
... ...
@@ -28,7 +28,7 @@ int init_put_byte(ByteIOContext *s,
28 28
                   int write_flag,
29 29
                   void *opaque,
30 30
                   int (*read_packet)(void *opaque, uint8_t *buf, int buf_size),
31
-                  void (*write_packet)(void *opaque, uint8_t *buf, int buf_size),
31
+                  int (*write_packet)(void *opaque, uint8_t *buf, int buf_size),
32 32
                   int (*seek)(void *opaque, offset_t offset, int whence))
33 33
 {
34 34
     s->buffer = buffer;
... ...
@@ -46,6 +46,7 @@ int init_put_byte(ByteIOContext *s,
46 46
     s->pos = 0;
47 47
     s->must_flush = 0;
48 48
     s->eof_reached = 0;
49
+    s->error = 0;
49 50
     s->is_streamed = 0;
50 51
     s->max_packet_size = 0;
51 52
     s->update_checksum= NULL;
... ...
@@ -57,8 +58,12 @@ int init_put_byte(ByteIOContext *s,
57 57
 static void flush_buffer(ByteIOContext *s)
58 58
 {
59 59
     if (s->buf_ptr > s->buffer) {
60
-        if (s->write_packet)
61
-            s->write_packet(s->opaque, s->buffer, s->buf_ptr - s->buffer);
60
+        if (s->write_packet && !s->error){
61
+            int ret= s->write_packet(s->opaque, s->buffer, s->buf_ptr - s->buffer);
62
+            if(ret < 0){
63
+                s->error = ret;
64
+            }
65
+        }
62 66
         if(s->update_checksum){
63 67
             s->checksum= s->update_checksum(s->checksum, s->checksum_ptr, s->buf_ptr - s->checksum_ptr);
64 68
             s->checksum_ptr= s->buffer;
... ...
@@ -172,6 +177,11 @@ int url_feof(ByteIOContext *s)
172 172
     return s->eof_reached;
173 173
 }
174 174
 
175
+int url_ferror(ByteIOContext *s)
176
+{
177
+    return s->error;
178
+}
179
+
175 180
 #ifdef CONFIG_ENCODERS
176 181
 void put_le32(ByteIOContext *s, unsigned int val)
177 182
 {
... ...
@@ -260,6 +270,8 @@ static void fill_buffer(ByteIOContext *s)
260 260
         /* do not modify buffer if EOF reached so that a seek back can
261 261
            be done without rereading data */
262 262
         s->eof_reached = 1;
263
+    if(len<0)
264
+        s->error= len;
263 265
     } else {
264 266
         s->pos += len;
265 267
         s->buf_ptr = s->buffer;
... ...
@@ -432,10 +444,10 @@ uint64_t get_be64(ByteIOContext *s)
432 432
 /* link with avio functions */
433 433
 
434 434
 #ifdef CONFIG_ENCODERS
435
-static void url_write_packet(void *opaque, uint8_t *buf, int buf_size)
435
+static int url_write_packet(void *opaque, uint8_t *buf, int buf_size)
436 436
 {
437 437
     URLContext *h = opaque;
438
-    url_write(h, buf, buf_size);
438
+    return url_write(h, buf, buf_size);
439 439
 }
440 440
 #else
441 441
 #define	url_write_packet NULL
... ...
@@ -609,7 +621,7 @@ typedef struct DynBuffer {
609 609
     uint8_t io_buffer[1];
610 610
 } DynBuffer;
611 611
 
612
-static void dyn_buf_write(void *opaque, uint8_t *buf, int buf_size)
612
+static int dyn_buf_write(void *opaque, uint8_t *buf, int buf_size)
613 613
 {
614 614
     DynBuffer *d = opaque;
615 615
     int new_size, new_allocated_size;
... ...
@@ -627,28 +639,32 @@ static void dyn_buf_write(void *opaque, uint8_t *buf, int buf_size)
627 627
     if (new_allocated_size > d->allocated_size) {
628 628
         d->buffer = av_realloc(d->buffer, new_allocated_size);
629 629
         if(d->buffer == NULL)
630
-             return ;
630
+             return -1234;
631 631
         d->allocated_size = new_allocated_size;
632 632
     }
633 633
     memcpy(d->buffer + d->pos, buf, buf_size);
634 634
     d->pos = new_size;
635 635
     if (d->pos > d->size)
636 636
         d->size = d->pos;
637
+    return buf_size;
637 638
 }
638 639
 
639
-static void dyn_packet_buf_write(void *opaque, uint8_t *buf, int buf_size)
640
+static int dyn_packet_buf_write(void *opaque, uint8_t *buf, int buf_size)
640 641
 {
641 642
     unsigned char buf1[4];
643
+    int ret;
642 644
 
643 645
     /* packetized write: output the header */
644 646
     buf1[0] = (buf_size >> 24);
645 647
     buf1[1] = (buf_size >> 16);
646 648
     buf1[2] = (buf_size >> 8);
647 649
     buf1[3] = (buf_size);
648
-    dyn_buf_write(opaque, buf1, 4);
650
+    ret= dyn_buf_write(opaque, buf1, 4);
651
+    if(ret < 0)
652
+        return ret;
649 653
 
650 654
     /* then the data */
651
-    dyn_buf_write(opaque, buf, buf_size);
655
+    return dyn_buf_write(opaque, buf, buf_size);
652 656
 }
653 657
 
654 658
 static int dyn_buf_seek(void *opaque, offset_t offset, int whence)
... ...
@@ -1996,11 +1996,16 @@ static void truncate_ts(AVStream *st, AVPacket *pkt){
1996 1996
  */
1997 1997
 int av_write_frame(AVFormatContext *s, AVPacket *pkt)
1998 1998
 {
1999
+    int ret;
2000
+
1999 2001
     compute_pkt_fields2(s->streams[pkt->stream_index], pkt);
2000 2002
     
2001 2003
     truncate_ts(s->streams[pkt->stream_index], pkt);
2002 2004
 
2003
-    return s->oformat->write_packet(s, pkt);
2005
+    ret= s->oformat->write_packet(s, pkt);
2006
+    if(!ret)
2007
+        ret= url_ferror(&s->pb);
2008
+    return ret;
2004 2009
 }
2005 2010
 
2006 2011
 /**
... ...
@@ -2111,6 +2116,8 @@ int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt){
2111 2111
         
2112 2112
         if(ret<0)
2113 2113
             return ret;
2114
+        if(url_ferror(&s->pb))
2115
+            return url_ferror(&s->pb);
2114 2116
     }
2115 2117
 }
2116 2118
 
... ...
@@ -2139,10 +2146,14 @@ int av_write_trailer(AVFormatContext *s)
2139 2139
         
2140 2140
         if(ret<0)
2141 2141
             goto fail;
2142
+        if(url_ferror(&s->pb))
2143
+            goto fail;
2142 2144
     }
2143 2145
 
2144 2146
     ret = s->oformat->write_trailer(s);
2145 2147
 fail:
2148
+    if(ret == 0)
2149
+       ret=url_ferror(&s->pb);
2146 2150
     for(i=0;i<s->nb_streams;i++)
2147 2151
         av_freep(&s->streams[i]->priv_data);
2148 2152
     av_freep(&s->priv_data);