Hi, what would be the correct way to create patches that won't be corrupted? I merely tried to copy what I have seen on the mailing-list before, apparently I didn't do a very good job ;)
Regards, Stephan Holljes On Sun, Mar 22, 2015 at 12:24 AM, Michael Niedermayer <michae...@gmx.at> wrote: > On Sat, Mar 21, 2015 at 11:00:09PM +0100, Stephan Holljes wrote: > > Hi, > > > > this is a patch for a proof-of-concept for an http server. > > > > Usage on the server side: > > > > ffmpeg -i test.mp3 -c copy -listen 1 -f mp3 http://0.0.0.0 > > > > Usage on the client side: > > > > ffplay http://localhost:8080 > > > > I looked at tls.c and tcp.c and copied parts of the code. > > Please comment. > > > > Regards, > > Stephan Holljes > > > > --- > > libavformat/http.c | 113 > > ++++++++++++++++++++++++++++++++++++++-------------- > > 1 file changed, 83 insertions(+), 30 deletions(-) > > > > diff --git a/libavformat/http.c b/libavformat/http.c > > index da3c9be..d61e4e2 100644 > > --- a/libavformat/http.c > > +++ b/libavformat/http.c > > @@ -96,8 +96,12 @@ typedef struct HTTPContext { > > int send_expect_100; > > char *method; > > int reconnect; > > + int listen; > > + int fd; > > + int header_sent; > > } HTTPContext; > > > > + > > #define OFFSET(x) offsetof(HTTPContext, x) > > #define D AV_OPT_FLAG_DECODING_PARAM > > #define E AV_OPT_FLAG_ENCODING_PARAM > > @@ -127,6 +131,7 @@ static const AVOption options[] = { > > { "end_offset", "try to limit the request to bytes preceding this > > offset", OFFSET(end_off), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT64_MAX, > D > > }, > > { "method", "Override the HTTP method", OFFSET(method), > > AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E }, > > { "reconnect", "auto reconnect after disconnect before EOF", > > OFFSET(reconnect), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, D }, > > + { "listen", "listen on HTTP", OFFSET(listen), AV_OPT_TYPE_INT, { > .i64 > > = 0 }, 0, 1, D }, > > it appears this patch has been corrupted by extra newlines from > word/line wrap > > please resend as an attachment > > [...] > -- > Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB > > Breaking DRM is a little like attempting to break through a door even > though the window is wide open and the only thing in the house is a bunch > of things you dont want and which you would get tomorrow for free anyway > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > >
diff --git a/libavformat/http.c b/libavformat/http.c index da3c9be..d61e4e2 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -96,8 +96,12 @@ typedef struct HTTPContext { int send_expect_100; char *method; int reconnect; + int listen; + int fd; + int header_sent; } HTTPContext; + #define OFFSET(x) offsetof(HTTPContext, x) #define D AV_OPT_FLAG_DECODING_PARAM #define E AV_OPT_FLAG_ENCODING_PARAM @@ -127,6 +131,7 @@ static const AVOption options[] = { { "end_offset", "try to limit the request to bytes preceding this offset", OFFSET(end_off), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT64_MAX, D }, { "method", "Override the HTTP method", OFFSET(method), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E }, { "reconnect", "auto reconnect after disconnect before EOF", OFFSET(reconnect), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, D }, + { "listen", "listen on HTTP", OFFSET(listen), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, D }, { NULL } }; @@ -299,8 +304,10 @@ int ff_http_averror(int status_code, int default_averror) static int http_open(URLContext *h, const char *uri, int flags, AVDictionary **options) { + struct addrinfo hints = { 0 }, *ai; HTTPContext *s = h->priv_data; - int ret; + int ret = -1, fd; + char portstr[] = "8080"; // allow non-root users for now if( s->seekable == 1 ) h->is_streamed = 0; @@ -320,11 +327,39 @@ static int http_open(URLContext *h, const char *uri, int flags, av_log(h, AV_LOG_WARNING, "No trailing CRLF found in HTTP header.\n"); } + if (s->listen) { + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags |= AI_PASSIVE; + ret = getaddrinfo(NULL, portstr, &hints, &ai); + if (ret) { + av_log(h, AV_LOG_ERROR, "borked"); + return AVERROR(EIO); + } + fd = ff_socket(ai->ai_family, + ai->ai_socktype, + ai->ai_protocol); + if (fd < 0) { + ret = ff_neterrno(); + freeaddrinfo(ai); + return -1; + } - ret = http_open_cnx(h, options); - if (ret < 0) - av_dict_free(&s->chained_options); - return ret; + fd = ff_listen_bind(fd, ai->ai_addr, ai->ai_addrlen, -1, h); + if (fd < 0) { + freeaddrinfo(ai); + return fd; + } + h->is_streamed = 1; + s->fd = fd; + freeaddrinfo(ai); + return 0; + } else { + ret = http_open_cnx(h, options); + if (ret < 0) + av_dict_free(&s->chained_options); + return ret; + } } static int http_getc(HTTPContext *s) @@ -1102,25 +1137,40 @@ static int http_write(URLContext *h, const uint8_t *buf, int size) char temp[11] = ""; /* 32-bit hex + CRLF + nul */ int ret; char crlf[] = "\r\n"; + char header[] = "HTTP 200 OK\r\n\r\n"; HTTPContext *s = h->priv_data; + if (!s->listen) { + if (!s->chunked_post) { + /* non-chunked data is sent without any special encoding */ + return ffurl_write(s->hd, buf, size); + } - if (!s->chunked_post) { - /* non-chunked data is sent without any special encoding */ - return ffurl_write(s->hd, buf, size); - } - - /* silently ignore zero-size data since chunk encoding that would - * signal EOF */ - if (size > 0) { - /* upload data using chunked encoding */ - snprintf(temp, sizeof(temp), "%x\r\n", size); + /* silently ignore zero-size data since chunk encoding that would + * signal EOF */ + if (size > 0) { + /* upload data using chunked encoding */ + snprintf(temp, sizeof(temp), "%x\r\n", size); - if ((ret = ffurl_write(s->hd, temp, strlen(temp))) < 0 || - (ret = ffurl_write(s->hd, buf, size)) < 0 || - (ret = ffurl_write(s->hd, crlf, sizeof(crlf) - 1)) < 0) - return ret; + if ((ret = ffurl_write(s->hd, temp, strlen(temp))) < 0 || + (ret = ffurl_write(s->hd, buf, size)) < 0 || + (ret = ffurl_write(s->hd, crlf, sizeof(crlf) - 1)) < 0) + return ret; + } + return size; + } else { + if (!s->header_sent) { + ret = send(s->fd, header, sizeof(header), MSG_NOSIGNAL); + s->header_sent = 1; + return ret < 0 ? ff_neterrno() : ret; + } + if (size > 0) { + ret = send(s->fd, buf, size, MSG_NOSIGNAL); + return ret < 0 ? ff_neterrno() : ret; + } else { + ret = -1; + } + return ret; } - return size; } static int http_shutdown(URLContext *h, int flags) @@ -1143,20 +1193,23 @@ static int http_close(URLContext *h) { int ret = 0; HTTPContext *s = h->priv_data; - + if (!s->listen) { #if CONFIG_ZLIB - inflateEnd(&s->inflate_stream); - av_freep(&s->inflate_buffer); + inflateEnd(&s->inflate_stream); + av_freep(&s->inflate_buffer); #endif /* CONFIG_ZLIB */ - if (!s->end_chunked_post) - /* Close the write direction by sending the end of chunked encoding. */ - ret = http_shutdown(h, h->flags); + if (!s->end_chunked_post) + /* Close the write direction by sending the end of chunked encoding. */ + ret = http_shutdown(h, h->flags); - if (s->hd) - ffurl_closep(&s->hd); - av_dict_free(&s->chained_options); - return ret; + if (s->hd) + ffurl_closep(&s->hd); + av_dict_free(&s->chained_options); + return ret; + } else { + return shutdown(s->fd, SHUT_RDWR); + } } static int64_t http_seek_internal(URLContext *h, int64_t off, int whence, int force_reconnect)
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel