diff mbox

[FFmpeg-devel] libavformat/aviobuf.c: don't treat 0 from read_packet as EOF

Message ID 20170603081659.7882-1-daniel.kucera@gmail.com
State Superseded
Headers show

Commit Message

Daniel Kucera June 3, 2017, 8:16 a.m. UTC
Signed-off-by: Daniel Kucera <daniel.kucera@gmail.com>
---
 libavformat/avio.c    |  2 +-
 libavformat/aviobuf.c | 18 ++++++++++--------
 libavformat/cache.c   |  2 +-
 libavformat/file.c    |  2 ++
 libavformat/subfile.c |  2 +-
 libavformat/wtvdec.c  |  4 ++--
 6 files changed, 17 insertions(+), 13 deletions(-)

Comments

Michael Niedermayer June 3, 2017, 5:57 p.m. UTC | #1
On Sat, Jun 03, 2017 at 10:16:59AM +0200, Daniel Kucera wrote:
> Signed-off-by: Daniel Kucera <daniel.kucera@gmail.com>
> ---
>  libavformat/avio.c    |  2 +-
>  libavformat/aviobuf.c | 18 ++++++++++--------
>  libavformat/cache.c   |  2 +-
>  libavformat/file.c    |  2 ++
>  libavformat/subfile.c |  2 +-
>  libavformat/wtvdec.c  |  4 ++--
>  6 files changed, 17 insertions(+), 13 deletions(-)

breaks rtp

example:

cvlc --play-and-exit ~/videos/matrixbench_mpeg2.mpg --sout="#rtp{dst=127.0.0.1,port=4444,sdp=rtsp://127.0.0.1:9080/test.sdp, mux=ts}" & ./ffmpeg -i rtp://127.0.0.1:4444 -t 1 -y out.avi


[...]
Michael Niedermayer June 3, 2017, 7:54 p.m. UTC | #2
On Sat, Jun 03, 2017 at 10:16:59AM +0200, Daniel Kucera wrote:
> Signed-off-by: Daniel Kucera <daniel.kucera@gmail.com>
> ---
>  libavformat/avio.c    |  2 +-
>  libavformat/aviobuf.c | 18 ++++++++++--------
>  libavformat/cache.c   |  2 +-
>  libavformat/file.c    |  2 ++
>  libavformat/subfile.c |  2 +-
>  libavformat/wtvdec.c  |  4 ++--
>  6 files changed, 17 insertions(+), 13 deletions(-)

looses Duration in output in:
cat ~/videos/matrixbench_mpeg2.mpg | ./ffprobe -read_ahead_limit -1 cache:pipe:0

[...]
Daniel Kucera June 3, 2017, 8:31 p.m. UTC | #3
2017-06-03 21:54 GMT+02:00 Michael Niedermayer <michael@niedermayer.cc>:
> On Sat, Jun 03, 2017 at 10:16:59AM +0200, Daniel Kucera wrote:
>> Signed-off-by: Daniel Kucera <daniel.kucera@gmail.com>
>> ---
>>  libavformat/avio.c    |  2 +-
>>  libavformat/aviobuf.c | 18 ++++++++++--------
>>  libavformat/cache.c   |  2 +-
>>  libavformat/file.c    |  2 ++
>>  libavformat/subfile.c |  2 +-
>>  libavformat/wtvdec.c  |  4 ++--
>>  6 files changed, 17 insertions(+), 13 deletions(-)
>
> looses Duration in output in:
> cat ~/videos/matrixbench_mpeg2.mpg | ./ffprobe -read_ahead_limit -1 cache:pipe:0
>

I fixed that RTP issue, I'll send updated patch. What does it mean
"looses Duration" ?
James Almer June 3, 2017, 9:04 p.m. UTC | #4
On 6/3/2017 5:31 PM, Daniel Kučera wrote:
> 2017-06-03 21:54 GMT+02:00 Michael Niedermayer <michael@niedermayer.cc>:
>> On Sat, Jun 03, 2017 at 10:16:59AM +0200, Daniel Kucera wrote:
>>> Signed-off-by: Daniel Kucera <daniel.kucera@gmail.com>
>>> ---
>>>  libavformat/avio.c    |  2 +-
>>>  libavformat/aviobuf.c | 18 ++++++++++--------
>>>  libavformat/cache.c   |  2 +-
>>>  libavformat/file.c    |  2 ++
>>>  libavformat/subfile.c |  2 +-
>>>  libavformat/wtvdec.c  |  4 ++--
>>>  6 files changed, 17 insertions(+), 13 deletions(-)
>>
>> looses Duration in output in:
>> cat ~/videos/matrixbench_mpeg2.mpg | ./ffprobe -read_ahead_limit -1 cache:pipe:0
>>
> 
> I fixed that RTP issue, I'll send updated patch. What does it mean
> "looses Duration" ?

The reported duration (and bitrate it seems) for the input file is lost,
and N/A is shown instead.

Without your patch:

[cache @ 0000000000ecac40] Inner protocol failed to seekback end : -40
[mpeg @ 00000000024f3740] start time for stream 0 is not set in
estimate_timings_from_pts
[cache @ 0000000000ecac40] Inner protocol failed to seekback end : -40
    Last message repeated 2 times
Input #0, mpeg, from 'cache:pipe:0':
  Duration: 00:03:07.66, start: 0.220000, bitrate: 5633 kb/s
    Stream #0:0[0x1bf]: Data: dvd_nav_packet
    Stream #0:1[0x1e0]: Video: mpeg2video (Main), yuv420p(tv,
bt470bg/bt470m/bt470m, bottom first), 720x576 [SAR 16:15 DAR 4:3], 25
fps, 25 tbr, 90k tbn, 50 tbc
    Stream #0:2[0x1c0]: Audio: mp2, 48000 Hz, stereo, s16p, 384 kb/s
Unsupported codec with id 100357 for input stream 0
[cache @ 0000000000ecac40] Statistics, cache hits:16 cache misses:4033


With it:

[cache @ 00000000010aac40] Inner protocol failed to seekback end : -40
    Last message repeated 1 times
Input #0, mpeg, from 'cache:pipe:0':
  Duration: N/A, start: 0.220000, bitrate: N/A
    Stream #0:0[0x1bf]: Data: dvd_nav_packet
    Stream #0:1[0x1e0]: Video: mpeg2video (Main), yuv420p(tv,
bt470bg/bt470m/bt470m, bottom first), 720x576 [SAR 16:15 DAR 4:3], 25
fps, 25 tbr, 90k tbn, 50 tbc
    Stream #0:2[0x1c0]: Audio: mp2, 48000 Hz, stereo, s16p, 384 kb/s
Unsupported codec with id 100357 for input stream 0
[cache @ 00000000010aac40] Statistics, cache hits:0 cache misses:4033
Daniel Kucera June 3, 2017, 9:11 p.m. UTC | #5
2017-06-03 23:04 GMT+02:00 James Almer <jamrial@gmail.com>:
> On 6/3/2017 5:31 PM, Daniel Kučera wrote:
>> 2017-06-03 21:54 GMT+02:00 Michael Niedermayer <michael@niedermayer.cc>:
>>> On Sat, Jun 03, 2017 at 10:16:59AM +0200, Daniel Kucera wrote:
>>>> Signed-off-by: Daniel Kucera <daniel.kucera@gmail.com>
>>>> ---
>>>>  libavformat/avio.c    |  2 +-
>>>>  libavformat/aviobuf.c | 18 ++++++++++--------
>>>>  libavformat/cache.c   |  2 +-
>>>>  libavformat/file.c    |  2 ++
>>>>  libavformat/subfile.c |  2 +-
>>>>  libavformat/wtvdec.c  |  4 ++--
>>>>  6 files changed, 17 insertions(+), 13 deletions(-)
>>>
>>> looses Duration in output in:
>>> cat ~/videos/matrixbench_mpeg2.mpg | ./ffprobe -read_ahead_limit -1 cache:pipe:0
>>>
>>
>> I fixed that RTP issue, I'll send updated patch. What does it mean
>> "looses Duration" ?
>
> The reported duration (and bitrate it seems) for the input file is lost,
> and N/A is shown instead.
>
> Without your patch:
>
> [cache @ 0000000000ecac40] Inner protocol failed to seekback end : -40
> [mpeg @ 00000000024f3740] start time for stream 0 is not set in
> estimate_timings_from_pts
> [cache @ 0000000000ecac40] Inner protocol failed to seekback end : -40
>     Last message repeated 2 times
> Input #0, mpeg, from 'cache:pipe:0':
>   Duration: 00:03:07.66, start: 0.220000, bitrate: 5633 kb/s
>     Stream #0:0[0x1bf]: Data: dvd_nav_packet
>     Stream #0:1[0x1e0]: Video: mpeg2video (Main), yuv420p(tv,
> bt470bg/bt470m/bt470m, bottom first), 720x576 [SAR 16:15 DAR 4:3], 25
> fps, 25 tbr, 90k tbn, 50 tbc
>     Stream #0:2[0x1c0]: Audio: mp2, 48000 Hz, stereo, s16p, 384 kb/s
> Unsupported codec with id 100357 for input stream 0
> [cache @ 0000000000ecac40] Statistics, cache hits:16 cache misses:4033
>
>
> With it:
>
> [cache @ 00000000010aac40] Inner protocol failed to seekback end : -40
>     Last message repeated 1 times
> Input #0, mpeg, from 'cache:pipe:0':
>   Duration: N/A, start: 0.220000, bitrate: N/A
>     Stream #0:0[0x1bf]: Data: dvd_nav_packet
>     Stream #0:1[0x1e0]: Video: mpeg2video (Main), yuv420p(tv,
> bt470bg/bt470m/bt470m, bottom first), 720x576 [SAR 16:15 DAR 4:3], 25
> fps, 25 tbr, 90k tbn, 50 tbc
>     Stream #0:2[0x1c0]: Audio: mp2, 48000 Hz, stereo, s16p, 384 kb/s
> Unsupported codec with id 100357 for input stream 0
> [cache @ 00000000010aac40] Statistics, cache hits:0 cache misses:4033
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Is it with the latest version I sent half an hour ago?

It seems to be working for me. Can you please provide your testing
file and command?

 cat fate-suite/mpeg2/matrixbench_mpeg2.lq1.mpg | ./ffprobe
-read_ahead_limit -1 cache:pipe:0
ffprobe version N-86331-gae37d3a1c4 Copyright (c) 2007-2017 the FFmpeg
developers
  built with gcc 6.3.0 (Ubuntu 6.3.0-12ubuntu2) 20170406
  configuration: --enable-debug=3 --enable-gpl --enable-libx264
  libavutil      55. 63.100 / 55. 63.100
  libavcodec     57. 96.101 / 57. 96.101
  libavformat    57. 72.101 / 57. 72.101
  libavdevice    57.  7.100 / 57.  7.100
  libavfilter     6. 90.100 /  6. 90.100
  libswscale      4.  7.101 /  4.  7.101
  libswresample   2.  8.100 /  2.  8.100
  libpostproc    54.  6.100 / 54.  6.100
[cache @ 0x55e680107560] Inner protocol failed to seekback end : -38
    Last message repeated 3 times
Input #0, mpeg, from 'cache:pipe:0':
  Duration: 00:00:00.96, start: 0.540000, bitrate: 1757 kb/s
    Stream #0:0[0x1e0]: Video: mpeg2video (Main), yuv420p(tv,
progressive), 716x236 [SAR 1:1 DAR 179:59], 25 fps, 25 tbr, 90k tbn,
50 tbc
[cache @ 0x55e680107560] Statistics, cache hits:10 cache misses:7
James Almer June 3, 2017, 9:17 p.m. UTC | #6
On 6/3/2017 6:11 PM, Daniel Kučera wrote:
> 2017-06-03 23:04 GMT+02:00 James Almer <jamrial@gmail.com>:
>> On 6/3/2017 5:31 PM, Daniel Kučera wrote:
>>> 2017-06-03 21:54 GMT+02:00 Michael Niedermayer <michael@niedermayer.cc>:
>>>> On Sat, Jun 03, 2017 at 10:16:59AM +0200, Daniel Kucera wrote:
>>>>> Signed-off-by: Daniel Kucera <daniel.kucera@gmail.com>
>>>>> ---
>>>>>  libavformat/avio.c    |  2 +-
>>>>>  libavformat/aviobuf.c | 18 ++++++++++--------
>>>>>  libavformat/cache.c   |  2 +-
>>>>>  libavformat/file.c    |  2 ++
>>>>>  libavformat/subfile.c |  2 +-
>>>>>  libavformat/wtvdec.c  |  4 ++--
>>>>>  6 files changed, 17 insertions(+), 13 deletions(-)
>>>>
>>>> looses Duration in output in:
>>>> cat ~/videos/matrixbench_mpeg2.mpg | ./ffprobe -read_ahead_limit -1 cache:pipe:0
>>>>
>>>
>>> I fixed that RTP issue, I'll send updated patch. What does it mean
>>> "looses Duration" ?
>>
>> The reported duration (and bitrate it seems) for the input file is lost,
>> and N/A is shown instead.
>>
>> Without your patch:
>>
>> [cache @ 0000000000ecac40] Inner protocol failed to seekback end : -40
>> [mpeg @ 00000000024f3740] start time for stream 0 is not set in
>> estimate_timings_from_pts
>> [cache @ 0000000000ecac40] Inner protocol failed to seekback end : -40
>>     Last message repeated 2 times
>> Input #0, mpeg, from 'cache:pipe:0':
>>   Duration: 00:03:07.66, start: 0.220000, bitrate: 5633 kb/s
>>     Stream #0:0[0x1bf]: Data: dvd_nav_packet
>>     Stream #0:1[0x1e0]: Video: mpeg2video (Main), yuv420p(tv,
>> bt470bg/bt470m/bt470m, bottom first), 720x576 [SAR 16:15 DAR 4:3], 25
>> fps, 25 tbr, 90k tbn, 50 tbc
>>     Stream #0:2[0x1c0]: Audio: mp2, 48000 Hz, stereo, s16p, 384 kb/s
>> Unsupported codec with id 100357 for input stream 0
>> [cache @ 0000000000ecac40] Statistics, cache hits:16 cache misses:4033
>>
>>
>> With it:
>>
>> [cache @ 00000000010aac40] Inner protocol failed to seekback end : -40
>>     Last message repeated 1 times
>> Input #0, mpeg, from 'cache:pipe:0':
>>   Duration: N/A, start: 0.220000, bitrate: N/A
>>     Stream #0:0[0x1bf]: Data: dvd_nav_packet
>>     Stream #0:1[0x1e0]: Video: mpeg2video (Main), yuv420p(tv,
>> bt470bg/bt470m/bt470m, bottom first), 720x576 [SAR 16:15 DAR 4:3], 25
>> fps, 25 tbr, 90k tbn, 50 tbc
>>     Stream #0:2[0x1c0]: Audio: mp2, 48000 Hz, stereo, s16p, 384 kb/s
>> Unsupported codec with id 100357 for input stream 0
>> [cache @ 00000000010aac40] Statistics, cache hits:0 cache misses:4033
>> _______________________________________________
>> ffmpeg-devel mailing list
>> ffmpeg-devel@ffmpeg.org
>> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> Is it with the latest version I sent half an hour ago?

Yes.

> 
> It seems to be working for me. Can you please provide your testing
> file and command?

I used the exact command Michael posted, with ffprobe on Windows.

> 
>  cat fate-suite/mpeg2/matrixbench_mpeg2.lq1.mpg | ./ffprobe
> -read_ahead_limit -1 cache:pipe:0
> ffprobe version N-86331-gae37d3a1c4 Copyright (c) 2007-2017 the FFmpeg
> developers
>   built with gcc 6.3.0 (Ubuntu 6.3.0-12ubuntu2) 20170406
>   configuration: --enable-debug=3 --enable-gpl --enable-libx264
>   libavutil      55. 63.100 / 55. 63.100
>   libavcodec     57. 96.101 / 57. 96.101
>   libavformat    57. 72.101 / 57. 72.101
>   libavdevice    57.  7.100 / 57.  7.100
>   libavfilter     6. 90.100 /  6. 90.100
>   libswscale      4.  7.101 /  4.  7.101
>   libswresample   2.  8.100 /  2.  8.100
>   libpostproc    54.  6.100 / 54.  6.100
> [cache @ 0x55e680107560] Inner protocol failed to seekback end : -38
>     Last message repeated 3 times
> Input #0, mpeg, from 'cache:pipe:0':
>   Duration: 00:00:00.96, start: 0.540000, bitrate: 1757 kb/s
>     Stream #0:0[0x1e0]: Video: mpeg2video (Main), yuv420p(tv,
> progressive), 716x236 [SAR 1:1 DAR 179:59], 25 fps, 25 tbr, 90k tbn,
> 50 tbc
> [cache @ 0x55e680107560] Statistics, cache hits:10 cache misses:7

That's not the sample I (and i assume Michael as well) tried.

http://samples.ffmpeg.org/benchmark/testsuite1/matrixbench_mpeg2.mpg
Which has one video, audio and data stream.
diff mbox

Patch

diff --git a/libavformat/avio.c b/libavformat/avio.c
index 1e79c9dd5c..bf803016b7 100644
--- a/libavformat/avio.c
+++ b/libavformat/avio.c
@@ -394,7 +394,7 @@  static inline int retry_transfer_wrapper(URLContext *h, uint8_t *buf,
                 av_usleep(1000);
             }
         } else if (ret < 1)
-            return (ret < 0 && ret != AVERROR_EOF) ? ret : len;
+            return (ret < 0) ? ret : len;
         if (ret) {
             fast_retries = FFMAX(fast_retries, 2);
             wait_since = 0;
diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c
index 1667e9f08b..40cff4dc56 100644
--- a/libavformat/aviobuf.c
+++ b/libavformat/aviobuf.c
@@ -556,13 +556,14 @@  static void fill_buffer(AVIOContext *s)
     if (s->read_packet)
         len = s->read_packet(s->opaque, dst, len);
     else
-        len = 0;
-    if (len <= 0) {
+        len = AVERROR_EOF;
+    if (len == AVERROR_EOF) {
         /* 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 if (len < 0) {
+        s->eof_reached = 1;
+        s->error= len;
     } else {
         s->pos += len;
         s->buf_ptr = dst;
@@ -630,13 +631,14 @@  int avio_read(AVIOContext *s, unsigned char *buf, int size)
                 // bypass the buffer and read data directly into buf
                 if(s->read_packet)
                     len = s->read_packet(s->opaque, buf, size);
-
-                if (len <= 0) {
+                if (len == AVERROR_EOF) {
                     /* 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;
+                    break;
+                } else if (len < 0) {
+                    s->eof_reached = 1;
+                    s->error= len;
                     break;
                 } else {
                     s->pos += len;
diff --git a/libavformat/cache.c b/libavformat/cache.c
index 6aabca2e78..54a40d018b 100644
--- a/libavformat/cache.c
+++ b/libavformat/cache.c
@@ -201,7 +201,7 @@  static int cache_read(URLContext *h, unsigned char *buf, int size)
     }
 
     r = ffurl_read(c->inner, buf, size);
-    if (r == 0 && size>0) {
+    if (r == AVERROR_EOF && size>0) {
         c->is_true_eof = 1;
         av_assert0(c->end >= c->logical_pos);
     }
diff --git a/libavformat/file.c b/libavformat/file.c
index 264542a36a..1fb83851c0 100644
--- a/libavformat/file.c
+++ b/libavformat/file.c
@@ -112,6 +112,8 @@  static int file_read(URLContext *h, unsigned char *buf, int size)
     ret = read(c->fd, buf, size);
     if (ret == 0 && c->follow)
         return AVERROR(EAGAIN);
+    if (ret == 0)
+        return AVERROR_EOF; 
     return (ret == -1) ? AVERROR(errno) : ret;
 }
 
diff --git a/libavformat/subfile.c b/libavformat/subfile.c
index fa971e1902..497cf85211 100644
--- a/libavformat/subfile.c
+++ b/libavformat/subfile.c
@@ -102,7 +102,7 @@  static int subfile_read(URLContext *h, unsigned char *buf, int size)
     int ret;
 
     if (rest <= 0)
-        return 0;
+        return AVERROR_EOF;
     size = FFMIN(size, rest);
     ret = ffurl_read(c->h, buf, size);
     if (ret >= 0)
diff --git a/libavformat/wtvdec.c b/libavformat/wtvdec.c
index 3ac4501306..ee19fd84da 100644
--- a/libavformat/wtvdec.c
+++ b/libavformat/wtvdec.c
@@ -65,7 +65,7 @@  static int64_t seek_by_sector(AVIOContext *pb, int64_t sector, int64_t offset)
 }
 
 /**
- * @return bytes read, 0 on end of file, or <0 on error
+ * @return bytes read, AVERROR_EOF on end of file, or <0 on error
  */
 static int wtvfile_read_packet(void *opaque, uint8_t *buf, int buf_size)
 {
@@ -76,7 +76,7 @@  static int wtvfile_read_packet(void *opaque, uint8_t *buf, int buf_size)
     if (wf->error || pb->error)
         return -1;
     if (wf->position >= wf->length || avio_feof(pb))
-        return 0;
+        return AVERROR_EOF;
 
     buf_size = FFMIN(buf_size, wf->length - wf->position);
     while(nread < buf_size) {