On 2 June 2010 00:01, Martin Storsjö <[email protected]> wrote:
> On Tue, 1 Jun 2010, Josh Allmann wrote:
>
>> On 1 June 2010 15:22, Josh Allmann <[email protected]> wrote:
>> >
>> > The first patch separates the initialization from the actual
>> > connection, which will enable delayed connections using the internal
>> > api.
>> >
>>
>> Ignore this one (for now).
>>
>> It  works within http.c, but not outside (eg, with rtsp) because
>> there's no way to initialize the URLContext without calling url_open
>> and hence http_open. Making http_open do delayed connections by
>> default will break API behavior.
>
> Exactly. What about making it work just as it does now, but adding e.g.
> some URL_DELAYOPEN flag, which changes its behaviour, which iirc Ronald
> suggested. Then you can do a normal url_open(..., URL_DELAYOPEN), set the
> custom headers and then open the actual connection?
>

That works too (although I must have missed Ronald's suggestion). It's
similar to something I suggested earlier on IRC, but I wanted to name
it URL_RTSP or something. I will take a look at that in the morning,
since it's simpler than my other solution, I'm sending another patch
anyway for posterity because I just finished it.

The patch splits url_open into ff_url_open which does the detection of
the protocol handler and allocates the URLContext.

url_open_protocol is likewise split into alloc_url (called from
ff_url_open), which does what it sounds. This actually breaks API by
only allocating on a null handler, which I need to check to avoid
allocating twice when calling from url_open. I can probably fix this
after some sleep.

> Also, as for replacing/adding headers.. I'm not sure that you'd want to
> skip all of the default headers if you're adding custom ones, e.g.
> User-Agent, Accept and Host can very well be kept, perhaps Connection:
> close, too.
>
> Ideally, the user code should be able to remove/replace these headers if
> it wants to, but use the default values if nothing is changed. But that
> requires a bit more complex data structure... Perhaps that's out of scope
> here, too.

Agreed, it will take quite a bit of work. The current method is
quick-n-dirty, but functional.

It might be a good idea to introduce some more flexibility into this
anyway -- I still haven't built a way to disable chunked encoding.
Another small ff_http method setting a context flag will do the trick,
but if we want to build something a little more flexible for all this,
now is the time to do it. AVOptions maybe?

Josh
diff --git a/libavformat/avio.c b/libavformat/avio.c
index 48399d0..52e626e 100644
--- a/libavformat/avio.c
+++ b/libavformat/avio.c
@@ -26,6 +26,7 @@
 #include "libavcodec/opt.h"
 #include "os_support.h"
 #include "avformat.h"
+#include "internal.h"
 #if CONFIG_NETWORK
 #include "network.h"
 #endif
@@ -73,11 +74,10 @@ int register_protocol(URLProtocol *protocol)
 }
 #endif
 
-int url_open_protocol (URLContext **puc, struct URLProtocol *up,
+static int alloc_url(URLContext **puc, struct URLProtocol *up,
                        const char *filename, int flags)
 {
     URLContext *uc;
-    int err;
 
 #if CONFIG_NETWORK
     if (!ff_network_init())
@@ -85,8 +85,11 @@ int url_open_protocol (URLContext **puc, struct URLProtocol *up,
 #endif
     uc = av_mallocz(sizeof(URLContext) + strlen(filename) + 1);
     if (!uc) {
-        err = AVERROR(ENOMEM);
-        goto fail;
+        *puc = NULL;
+#if CONFIG_NETWORK
+        ff_network_close();
+#endif
+        return AVERROR(ENOMEM);
     }
 #if LIBAVFORMAT_VERSION_MAJOR >= 53
     uc->av_class = &urlcontext_class;
@@ -97,6 +100,27 @@ int url_open_protocol (URLContext **puc, struct URLProtocol *up,
     uc->flags = flags;
     uc->is_streamed = 0; /* default = not streamed */
     uc->max_packet_size = 0; /* default: stream file */
+
+    *puc = uc;
+
+    return 0;
+}
+
+int url_open_protocol(URLContext **puc, struct URLProtocol *up,
+                       const char *filename, int flags)
+{
+    URLContext *uc;
+    int err;
+
+    uc = *puc;
+
+    // allocate url context if needed
+    if (!uc) { //XXX breaks api!!
+        if (0 != (err = alloc_url(&uc, up, filename, flags)))
+            goto fail;
+        *puc = uc;
+    }
+
     err = up->url_open(uc, filename, flags);
     if (err < 0) {
         av_free(uc);
@@ -108,7 +132,6 @@ int url_open_protocol (URLContext **puc, struct URLProtocol *up,
        || !strcmp(up->name, "file"))
         if(!uc->is_streamed && url_seek(uc, 0, SEEK_SET) < 0)
             uc->is_streamed= 1;
-    *puc = uc;
     return 0;
  fail:
     *puc = NULL;
@@ -120,6 +143,16 @@ int url_open_protocol (URLContext **puc, struct URLProtocol *up,
 
 int url_open(URLContext **puc, const char *filename, int flags)
 {
+    if (!*puc) { //XXX breaks api!
+        int err = ff_url_init(puc, filename, flags);
+        if (0 != err)
+            return err;
+    }
+    return url_open_protocol(puc, (*puc)->prot, filename, flags);
+}
+
+int ff_url_init(URLContext **puc, const char *filename, int flags)
+{
     URLProtocol *up;
     const char *p;
     char proto_str[128], *q;
@@ -145,7 +178,7 @@ int url_open(URLContext **puc, const char *filename, int flags)
     up = first_protocol;
     while (up != NULL) {
         if (!strcmp(proto_str, up->name))
-            return url_open_protocol (puc, up, filename, flags);
+            return alloc_url(puc, up, filename, flags);
         up = up->next;
     }
     *puc = NULL;
diff --git a/libavformat/internal.h b/libavformat/internal.h
index 358959c..74b03f2 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -173,4 +173,6 @@ void ff_sdp_write_media(char *buff, int size, AVCodecContext *c,
 int ff_write_chained(AVFormatContext *dst, int dst_stream, AVPacket *pkt,
                      AVFormatContext *src);
 
+int ff_url_init(URLContext **puc, const char *filename, int flags);
+
 #endif /* AVFORMAT_INTERNAL_H */
_______________________________________________
FFmpeg-soc mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-soc

Reply via email to