On Sun, 3 Jun 2012, Anton Khirnov wrote:
This makes it easier to switch between native rtmp and librtmp.
---
libavformat/librtmp.c | 111 ++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 96 insertions(+), 15 deletions(-)
diff --git a/libavformat/librtmp.c b/libavformat/librtmp.c
index 8883bbc..0dbcad5 100644
--- a/libavformat/librtmp.c
+++ b/libavformat/librtmp.c
@@ -24,13 +24,22 @@
* RTMP protocol based on http://rtmpdump.mplayerhq.hu/ librtmp
*/
+#include "libavutil/avstring.h"
#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
#include "avformat.h"
#include "url.h"
#include <librtmp/rtmp.h>
#include <librtmp/log.h>
+typedef struct LibRTMPContext {
+ const AVClass *class;
+ RTMP rtmp;
+ char *app;
+ char *playpath;
+} LibRTMPContext;
+
static void rtmp_log(int level, const char *fmt, va_list args)
{
switch (level) {
@@ -49,7 +58,8 @@ static void rtmp_log(int level, const char *fmt, va_list args)
static int rtmp_close(URLContext *s)
{
- RTMP *r = s->priv_data;
+ LibRTMPContext *ctx = s->priv_data;
+ RTMP *r = &ctx->rtmp;
RTMP_Close(r);
return 0;
@@ -69,8 +79,10 @@ static int rtmp_close(URLContext *s)
*/
static int rtmp_open(URLContext *s, const char *uri, int flags)
{
- RTMP *r = s->priv_data;
- int rc;
+ LibRTMPContext *ctx = s->priv_data;
+ RTMP *r = &ctx->rtmp;
+ int rc = 0;
+ char *filename = s->filename;
switch (av_log_get_level()) {
default:
@@ -84,8 +96,43 @@ static int rtmp_open(URLContext *s, const char *uri, int
flags)
RTMP_LogSetLevel(rc);
RTMP_LogSetCallback(rtmp_log);
+ if (ctx->app || ctx->playpath) {
+ int len = strlen(s->filename);
+ char *space = strchr(s->filename, ' ');
+ int trailing_slash;
+
+ if (!len || s->filename[0] == ' ')
+ return AVERROR(EINVAL);
+
+ trailing_slash = space ? *(space - 1) == '/' :
+ *(s->filename + len- 1) == '/';
+
+ if (ctx->app)
+ len += strlen(ctx->app);
+ if (ctx->playpath)
+ len += strlen(ctx->playpath);
+
+ len += 3; // terminator + two slashes
+ if (!(filename = av_malloc(len)))
+ return AVERROR(ENOMEM);
+
+ av_strlcpy(filename, s->filename, space ? space - s->filename : len);
+ if (ctx->app) {
+ if (!trailing_slash)
+ av_strlcat(filename, "/", len);
+ av_strlcat(filename, ctx->app, len);
+ }
+ if (ctx->playpath) {
+ if (ctx->app || !trailing_slash)
+ av_strlcat(filename, "/", len);
+ av_strlcat(filename, ctx->playpath, len);
+ }
+ if (space)
+ av_strlcat(filename, space, len);
+ }
+
This looks really messy and doesn't really work as well as you'd hope (I
think) - I guess this wouldn't work if you'd do something like this:
-rtmp_app some/app -rtmp_playpath long/play/path -i
rtmp://server/some/app/and/the/nominal/path
(Namely, the full path is used as tcUrl in the connect call, I think - it
at least is fully supported to do this.)
Also - if this works, why do you need to specify the playpath and app
separately? Why not just use a plain url for both the native rtmp and
librtmp? If you need to specify them separately, it's normally a case
where the built-in splitting heuristic doesn't do the right thing, so then
it wouldn't work to construct it into one single url for librtmp either.
However, librtmp has options similar to avoptions. Would it work better if
you'd construct the url into "rtmp://server/foo/bar app=app/path
playpath=play/path"? Then the values are passed separately all the way,
which is half of the point of specifying them separately using avoptions
in the first place.
// Martin
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel