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