diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-04-18 00:18:21 +0400 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-04-18 02:28:06 +0400 |
commit | 123272374180d8dc3ce9dff50f0c77d5b3b3341f (patch) | |
tree | 2c2add85161e74ebe6d4301a6607adc521112582 /libavformat/rtmpproto.c | |
parent | a66675268f63dd6794ce946c7edbcb8b49ae0f13 (diff) | |
parent | 0f96f0d9968a767ead3aec823fcdfb78f26f7be7 (diff) |
Merge remote-tracking branch 'qatar/master'
* qatar/master:
aacenc: Fix issues with huge values of bit_rate.
dv_tablegen: Drop unnecessary av_unused attribute from dv_vlc_map_tableinit().
proresenc: multithreaded quantiser search
riff: use bps instead of bits_per_coded_sample in the WAVEFORMATEXTENSIBLE header
avconv: only set the "channels" option when it exists for the specified input format
avplay: update get_buffer to be inline with avconv
aacdec: More robust output configuration.
faac: Fix multi-channel ordering
faac: Add .channel_layouts
rtmp: Support 'rtmp_playpath', an option which overrides the stream identifier
rtmp: Support 'rtmp_app', an option which overrides the name of application
avutil: add better documentation for AVSampleFormat
Conflicts:
libavcodec/aac.h
libavcodec/aacdec.c
libavcodec/aacenc.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat/rtmpproto.c')
-rw-r--r-- | libavformat/rtmpproto.c | 67 |
1 files changed, 58 insertions, 9 deletions
diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index 7a47ad2e68..521e9b8c6a 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,9 @@ //#define DEBUG +#define APP_MAX_LENGTH 128 +#define PLAYPATH_MAX_LENGTH 256 + /** RTMP protocol handler state */ typedef enum { STATE_START, ///< client has not done anything yet @@ -56,12 +60,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 *playpath; ///< stream identifier to play (with possible "mp4:" prefix) + 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 +827,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 +853,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,14 +884,29 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) } } } - if (!strchr(fname, ':') && - (!strcmp(fname + strlen(fname) - 4, ".f4v") || - !strcmp(fname + strlen(fname) - 4, ".mp4"))) { - memcpy(rt->playpath, "mp4:", 5); - } else { - rt->playpath[0] = 0; + + if (old_app) { + // The name of application has been defined by the user, override it. + av_free(rt->app); + rt->app = old_app; + } + + if (!rt->playpath) { + rt->playpath = av_malloc(PLAYPATH_MAX_LENGTH); + if (!rt->playpath) { + rtmp_close(s); + return AVERROR(ENOMEM); + } + + if (!strchr(fname, ':') && + (!strcmp(fname + strlen(fname) - 4, ".f4v") || + !strcmp(fname + strlen(fname) - 4, ".mp4"))) { + memcpy(rt->playpath, "mp4:", 5); + } else { + rt->playpath[0] = 0; + } + strncat(rt->playpath, fname, PLAYPATH_MAX_LENGTH - 5); } - strncat(rt->playpath, fname, sizeof(rt->playpath) - 5); rt->client_report_size = 1048576; rt->bytes_read = 0; @@ -1013,6 +1044,23 @@ 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}, + {"rtmp_playpath", "Stream identifier to play or to publish", OFFSET(playpath), 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 +1069,5 @@ URLProtocol ff_rtmp_protocol = { .url_close = rtmp_close, .priv_data_size = sizeof(RTMPContext), .flags = URL_PROTOCOL_FLAG_NETWORK, + .priv_data_class= &rtmp_class, }; |