summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libavformat/rtmpproto.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c
index 76835592d3..1d27c6f8e8 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;
+
+ 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,22 @@ 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
+#define ENC AV_OPT_FLAG_ENCODING_PARAM
+
+static const AVOption rtmp_options[] = {
+ {"rtmp_app", "Name of application to connect to on the RTMP server", OFFSET(app), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
+ { 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 +1059,5 @@ URLProtocol ff_rtmp_protocol = {
.url_close = rtmp_close,
.priv_data_size = sizeof(RTMPContext),
.flags = URL_PROTOCOL_FLAG_NETWORK,
+ .priv_data_class= &rtmp_class,
};