This option is the name of application to connect on the RTMP server.
Sometimes the URL parser cannot determine the app name automatically,
so it must be given explicitly using this option (ie. -application).
---
libavformat/rtmpproto.c | 40 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 39 insertions(+), 1 deletion(-)
diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c
index 7683559..946eaea 100644
--- a/libavformat/rtmpproto.c
+++ b/libavformat/rtmpproto.c
@@ -28,6 +28,7 @@
#include "libavutil/avstring.h"
#include "libavutil/intfloat.h"
#include "libavutil/lfg.h"
+#include "libavutil/opt.h"
#include "libavutil/sha.h"
#include "avformat.h"
#include "internal.h"
@@ -41,6 +42,8 @@
//#define DEBUG
+#define APP_MAX_LENGTH 128
+
/** RTMP protocol handler state */
typedef enum {
STATE_START, ///< client has not done anything yet
@@ -56,12 +59,13 @@ typedef enum {
/** protocol handler context */
typedef struct RTMPContext {
+ const AVClass *class;
URLContext* stream; ///< TCP stream used in
interactions with RTMP server
RTMPPacket prev_pkt[2][RTMP_CHANNELS]; ///< packet history used when
reading and sending packets
int chunk_size; ///< size of the chunks RTMP
packets are divided into
int is_input; ///< input/output flag
char playpath[256]; ///< path to filename to play
(with possible "mp4:" prefix)
- char app[128]; ///< application
+ char *app; ///< name of application
ClientState state; ///< current state
int main_channel_id; ///< an additional channel ID
which is used for some invocations
uint8_t* flv_data; ///< buffer with data for demuxer
@@ -822,6 +826,7 @@ static int rtmp_open(URLContext *s, const char *uri, int
flags)
{
RTMPContext *rt = s->priv_data;
char proto[8], hostname[256], path[1024], *fname;
+ char *old_app;
uint8_t buf[2048];
int port;
int ret;
@@ -847,6 +852,16 @@ static int rtmp_open(URLContext *s, const char *uri, int
flags)
rt->chunk_size = 128;
rt->state = STATE_HANDSHAKED;
+
+ // Keep the application name when it has been defined by the user.
+ old_app = rt->app ? av_strdup(rt->app) : NULL;
+
+ rt->app = av_malloc(APP_MAX_LENGTH);
+ if (!rt->app) {
+ rtmp_close(s);
+ return AVERROR(ENOMEM);
+ }
+
//extract "app" part from path
if (!strncmp(path, "/ondemand/", 10)) {
fname = path + 10;
@@ -868,6 +883,13 @@ static int rtmp_open(URLContext *s, const char *uri, int
flags)
}
}
}
+
+ if (old_app) {
+ // The name of application has been defined by the user, override it.
+ av_free(rt->app);
+ rt->app = old_app;
+ }
+
if (!strchr(fname, ':') &&
(!strcmp(fname + strlen(fname) - 4, ".f4v") ||
!strcmp(fname + strlen(fname) - 4, ".mp4"))) {
@@ -1013,6 +1035,21 @@ static int rtmp_write(URLContext *s, const uint8_t *buf,
int size)
return size;
}
+#define OFFSET(x) offsetof(RTMPContext, x)
+#define DEC AV_OPT_FLAG_DECODING_PARAM
+
+static const AVOption rtmp_options[] = {
+ {"application", "Name of application to connect to on the RTMP server",
OFFSET(app), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
+ { NULL },
+};
+
+static const AVClass rtmp_class = {
+ .class_name = "rtmp",
+ .item_name = av_default_item_name,
+ .option = rtmp_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
URLProtocol ff_rtmp_protocol = {
.name = "rtmp",
.url_open = rtmp_open,
@@ -1021,4 +1058,5 @@ URLProtocol ff_rtmp_protocol = {
.url_close = rtmp_close,
.priv_data_size = sizeof(RTMPContext),
.flags = URL_PROTOCOL_FLAG_NETWORK,
+ .priv_data_class= &rtmp_class,
};
--
1.7.10
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel