Opened 11 years ago
Last modified 11 years ago
#3127 new defect
Video stream publishing via RTMPT
Reported by: | GoodvinJ | Owned by: | |
---|---|---|---|
Priority: | normal | Component: | avformat |
Version: | git-master | Keywords: | |
Cc: | Blocked By: | ||
Blocking: | Reproduced by developer: | no | |
Analyzed by developer: | no |
Description
I have the latest FFMPEG built with librtmp support.
I'm trying to publish video stream to RED5 media server via RTMPT, but I see only few seconds of video (after that FFMPEG stops sending video).
When I use RTMP (not RTMPT) there is no such trouble.
On the other hand Flash Player publishes stream over RTMPT to RED5 without issues.
Also I've tried to build FFMPEG without librtmp support, but FFMPEG hangs on avio_open in this case.
Here is a log after avio_open call:
2013-11-12 20:05:50.031 [2824 ] DEBUG [http @ 01076140] request: POST /open/1 HTTP/1.1
Accept: */*
Connection: keep-alive
Host: localhost:5080
Content-Length: 1
Cache-Control: no-cache
Content-type: application/x-fcs
User-Agent: Shockwave Flash
2013-11-12 20:05:50.037 [2824 ] DEBUG [http @ 01076140] header='HTTP/1.1 200 OK'
2013-11-12 20:05:50.037 [2824 ] DEBUG [http @ 01076140] http_code=200
2013-11-12 20:05:50.037 [2824 ] DEBUG [http @ 01076140] header='Server: Apache-Coyote/1.1'
2013-11-12 20:05:50.038 [2824 ] DEBUG [http @ 01076140] header='Connection: Keep-Alive'
2013-11-12 20:05:50.038 [2824 ] DEBUG [http @ 01076140] header='Cache-Control: no-cache'
2013-11-12 20:05:50.038 [2824 ] DEBUG [http @ 01076140] header='Content-Type: application/x-fcs'
2013-11-12 20:05:50.039 [2824 ] DEBUG [http @ 01076140] header='Content-Length: 14'
2013-11-12 20:05:50.039 [2824 ] DEBUG [http @ 01076140] header='Date: Tue, 12 Nov 2013 13:05:50 GMT'
2013-11-12 20:05:50.040 [2824 ] DEBUG [http @ 01076140] header=
That's all - avio_open never returns.
I use the following command line for the test:
ffmpeg -re -i file.flv -acodec copy -vcodec h264 -f flv rtmpt://localhost:5080/oflaDemo/stream1384247072828
Attachments (2)
Change History (9)
comment:1 by , 11 years ago
comment:2 by , 11 years ago
I'd tried older versions, but they didn't work too.
Maybe at some point in the past it worked, I don't know.
comment:3 by , 11 years ago
I've found the reason of hangs in "avio_open":
"rtmp_http_open" tries to read server reply with unique id and calls "ffurl_read".
It expects that "ffurl_read" returns AVERROR_EOF on completion, but "ffurl_read" returns 0.
It's because "ffurl_read" calls "retry_transfer_wrapper" which calls "http_read" (as transfer_func).
"http_read" returns AVERROR_EOF, but there is the code:
} else if (ret < 1) return (ret < 0 && ret != AVERROR_EOF) ? ret : len;
so "retry_transfer_wrapper" returns len==0 instead of AVERROR_EOF, and "ffurl_read" returns 0.
Then "rtmp_http_open" calls "ffurl_read" and so on.
I'd fixed this by the following code in "rtmp_http_open":
for (;;) { ret = ffurl_read(rt->stream, rt->client_id + off, sizeof(rt->client_id) - off); if (ret == 0 || ret == AVERROR_EOF) break; if (ret < 0) goto fail; off += ret; if (off == sizeof(rt->client_id)) { ret = AVERROR(EIO); goto fail; } }
Next issue occurs in "rtmp_handshake" (it hangs too).
On handshake "rtmp_http_read" is called, "rtmp_http_read" calls "ffurl_read" and expects AVERROR_EOF on completion. But "ffurl_read" returns 0 again, so we get an infinite loop there.
I'd changed "rtmp_http_read":
do { ret = ffurl_read(rt->stream, buf + off, size); if (ret < 0 && ret != AVERROR_EOF) return ret; if (ret == 0 || ret == AVERROR_EOF) { if (rt->finishing) {
After these changes I'd reverted all my changes and changed only these lines in "retry_transfer_wrapper":
} else if (ret < 1) return (ret < 0 && ret != AVERROR_EOF) ? ret : len;
to
} else if (ret < 1) return (ret < 0) ? ret : len;
Now FFMPEG sends video over RTMPT (without librtmp support).
comment:4 by , 11 years ago
Component: | undetermined → avformat |
---|
comment:5 by , 11 years ago
Please send your patch - made with git format-patch
- to the ffmpeg-devel mailing list where it can be discussed.
comment:6 by , 11 years ago
Priority: | important → normal |
---|
by , 11 years ago
Attachment: | 0001-Partial-fix-for-the-ticket-3127-Video-stream-publish.patch added |
---|
Fix for the avio_open hangs
comment:7 by , 11 years ago
I've found that "ffurl_read" can return 0 by the specification:
/** * Read up to size bytes from the resource accessed by h, and store * the read bytes in buf. * * @return The number of bytes actually read, or a negative value * corresponding to an AVERROR code in case of error. A value of zero * indicates that it is not possible to read more from the accessed * resource (except if the value of the size argument is also zero). */ int ffurl_read(URLContext *h, unsigned char *buf, int size);
So the right patch must check "ffurl_read" result on 0, and the old patch is invalid.
by , 11 years ago
Attachment: | 0001-Partial-fix-for-the-ticket-3127-second-try.patch added |
---|
Patch - second try
Is this a regression (did it work with older versions of FFmpeg)?