diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-05-10 22:41:29 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-05-10 23:30:42 +0200 |
commit | 015903294ca983f007ab5cae098a54013e77f2f6 (patch) | |
tree | 66838f53dca82964270a1938692489c36e1fb1b0 /libavformat | |
parent | 2a793ff2bf2197f36db3bf296668d44915142d03 (diff) | |
parent | 110d0cdc9d1ec414a658f841a3fbefbf6f796d61 (diff) | |
download | ffmpeg-015903294ca983f007ab5cae098a54013e77f2f6.tar.gz |
Merge remote-tracking branch 'qatar/master'
* qatar/master: (25 commits)
rv40dsp x86: MMX/MMX2/3DNow/SSE2/SSSE3 implementations of MC
ape: Use unsigned integer maths
arm: dsputil: fix overreads in put/avg_pixels functions
h264: K&R formatting cosmetics for header files (part II/II)
h264: K&R formatting cosmetics for header files (part I/II)
rtmp: Implement check bandwidth notification.
rtmp: Support 'rtmp_swfurl', an option which specifies the URL of the SWF player.
rtmp: Support 'rtmp_flashver', an option which overrides the version of the Flash plugin.
rtmp: Support 'rtmp_tcurl', an option which overrides the URL of the target stream.
cmdutils: Add fallback case to switch in check_stream_specifier().
sctp: be consistent with socket option level
configure: Add _XOPEN_SOURCE=600 to Solaris preprocessor flags.
vcr1enc: drop pointless empty encode_init() wrapper function
vcr1: drop pointless write-only AVCodecContext member from VCR1Context
vcr1: group encoder code together to save #ifdefs
vcr1: cosmetics: K&R prettyprinting, typos, parentheses, dead code, comments
mov: make one comment slightly more specific
lavr: replace the SSE version of ff_conv_fltp_to_flt_6ch() with SSE4 and AVX
lavfi: move audio-related functions to a separate file.
lavfi: remove some audio-related function from public API.
...
Conflicts:
cmdutils.c
libavcodec/h264.h
libavcodec/h264_mvpred.h
libavcodec/vcr1.c
libavfilter/avfilter.c
libavfilter/avfilter.h
libavfilter/defaults.c
libavfilter/internal.h
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat')
-rw-r--r-- | libavformat/mov.c | 2 | ||||
-rw-r--r-- | libavformat/rtmpproto.c | 72 | ||||
-rw-r--r-- | libavformat/sctp.c | 2 |
3 files changed, 61 insertions, 15 deletions
diff --git a/libavformat/mov.c b/libavformat/mov.c index 240bccf402..9a2a59f36c 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1051,7 +1051,7 @@ static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom) return AVERROR_INVALIDDATA; if (atom.size >= 10) { - // Broken files created by legacy versions of Libav and FFmpeg will + // Broken files created by legacy versions of libavformat will // wrap a whole fiel atom inside of a glbl atom. unsigned size = avio_rb32(pb); unsigned type = avio_rl32(pb); diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index 2feb2409ba..c7db91de9e 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -44,6 +44,8 @@ #define APP_MAX_LENGTH 128 #define PLAYPATH_MAX_LENGTH 256 +#define TCURL_MAX_LENGTH 512 +#define FLASHVER_MAX_LENGTH 64 /** RTMP protocol handler state */ typedef enum { @@ -82,6 +84,9 @@ typedef struct RTMPContext { int flv_header_bytes; ///< number of initialized bytes in flv_header int nb_invokes; ///< keeps track of invoke messages int create_stream_invoke; ///< invoke id for the create stream command + char* tcurl; ///< url of the target stream + char* flashver; ///< version of the flash plugin + char* swfurl; ///< url of the swf player } RTMPContext; #define PLAYER_KEY_OPEN_PART_LEN 30 ///< length of partial key used for first client digest signing @@ -110,35 +115,34 @@ static const uint8_t rtmp_server_key[] = { /** * Generate 'connect' call and send it to the server. */ -static void gen_connect(URLContext *s, RTMPContext *rt, const char *proto, - const char *host, int port) +static void gen_connect(URLContext *s, RTMPContext *rt) { RTMPPacket pkt; - uint8_t ver[64], *p; - char tcurl[512]; + uint8_t *p; ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0, 4096); p = pkt.data; - ff_url_join(tcurl, sizeof(tcurl), proto, NULL, host, port, "/%s", rt->app); ff_amf_write_string(&p, "connect"); ff_amf_write_number(&p, ++rt->nb_invokes); ff_amf_write_object_start(&p); ff_amf_write_field_name(&p, "app"); ff_amf_write_string(&p, rt->app); - if (rt->is_input) { - snprintf(ver, sizeof(ver), "%s %d,%d,%d,%d", RTMP_CLIENT_PLATFORM, RTMP_CLIENT_VER1, - RTMP_CLIENT_VER2, RTMP_CLIENT_VER3, RTMP_CLIENT_VER4); - } else { - snprintf(ver, sizeof(ver), "FMLE/3.0 (compatible; %s)", LIBAVFORMAT_IDENT); + if (!rt->is_input) { ff_amf_write_field_name(&p, "type"); ff_amf_write_string(&p, "nonprivate"); } ff_amf_write_field_name(&p, "flashVer"); - ff_amf_write_string(&p, ver); + ff_amf_write_string(&p, rt->flashver); + + if (rt->swfurl) { + ff_amf_write_field_name(&p, "swfUrl"); + ff_amf_write_string(&p, rt->swfurl); + } + ff_amf_write_field_name(&p, "tcUrl"); - ff_amf_write_string(&p, tcurl); + ff_amf_write_string(&p, rt->tcurl); if (rt->is_input) { ff_amf_write_field_name(&p, "fpad"); ff_amf_write_bool(&p, 0); @@ -369,6 +373,25 @@ static void gen_server_bw(URLContext *s, RTMPContext *rt) } /** + * Generate check bandwidth message and send it to the server. + */ +static void gen_check_bw(URLContext *s, RTMPContext *rt) +{ + RTMPPacket pkt; + uint8_t *p; + + ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0, 21); + + p = pkt.data; + ff_amf_write_string(&p, "_checkbw"); + ff_amf_write_number(&p, ++rt->nb_invokes); + ff_amf_write_null(&p); + + ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]); + ff_rtmp_packet_destroy(&pkt); +} + +/** * Generate report on bytes read so far and send it to the server. */ static void gen_bytes_read(URLContext *s, RTMPContext *rt, uint32_t ts) @@ -687,6 +710,8 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt) if (!t && !strcmp(tmpstr, "NetStream.Play.Stop")) rt->state = STATE_STOPPED; if (!t && !strcmp(tmpstr, "NetStream.Play.UnpublishNotify")) rt->state = STATE_STOPPED; if (!t && !strcmp(tmpstr, "NetStream.Publish.Start")) rt->state = STATE_PUBLISHING; + } else if (!memcmp(pkt->data, "\002\000\010onBWDone", 11)) { + gen_check_bw(s, rt); } break; } @@ -910,13 +935,31 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) strncat(rt->playpath, fname, PLAYPATH_MAX_LENGTH - 5); } + if (!rt->tcurl) { + rt->tcurl = av_malloc(TCURL_MAX_LENGTH); + ff_url_join(rt->tcurl, TCURL_MAX_LENGTH, proto, NULL, hostname, + port, "/%s", rt->app); + } + + if (!rt->flashver) { + rt->flashver = av_malloc(FLASHVER_MAX_LENGTH); + if (rt->is_input) { + snprintf(rt->flashver, FLASHVER_MAX_LENGTH, "%s %d,%d,%d,%d", + RTMP_CLIENT_PLATFORM, RTMP_CLIENT_VER1, RTMP_CLIENT_VER2, + RTMP_CLIENT_VER3, RTMP_CLIENT_VER4); + } else { + snprintf(rt->flashver, FLASHVER_MAX_LENGTH, + "FMLE/3.0 (compatible; %s)", LIBAVFORMAT_IDENT); + } + } + rt->client_report_size = 1048576; rt->bytes_read = 0; rt->last_bytes_read = 0; av_log(s, AV_LOG_DEBUG, "Proto = %s, path = %s, app = %s, fname = %s\n", proto, path, rt->app, rt->playpath); - gen_connect(s, rt, proto, hostname, port); + gen_connect(s, rt); do { ret = get_packet(s, 1); @@ -1052,11 +1095,14 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size) 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_flashver", "Version of the Flash plugin used to run the SWF player.", OFFSET(flashver), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC}, {"rtmp_live", "Specify that the media is a live stream.", OFFSET(live), AV_OPT_TYPE_INT, {-2}, INT_MIN, INT_MAX, DEC, "rtmp_live"}, {"any", "both", 0, AV_OPT_TYPE_CONST, {-2}, 0, 0, DEC, "rtmp_live"}, {"live", "live stream", 0, AV_OPT_TYPE_CONST, {-1}, 0, 0, DEC, "rtmp_live"}, {"recorded", "recorded stream", 0, AV_OPT_TYPE_CONST, {0}, 0, 0, DEC, "rtmp_live"}, {"rtmp_playpath", "Stream identifier to play or to publish", OFFSET(playpath), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC}, + {"rtmp_swfurl", "URL of the SWF player. By default no value will be sent", OFFSET(swfurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC}, + {"rtmp_tcurl", "URL of the target stream. Defaults to rtmp://host[:port]/app.", OFFSET(tcurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC}, { NULL }, }; diff --git a/libavformat/sctp.c b/libavformat/sctp.c index 3823e03ebe..817b0049a9 100644 --- a/libavformat/sctp.c +++ b/libavformat/sctp.c @@ -227,7 +227,7 @@ static int sctp_open(URLContext *h, const char *uri, int flags) if (s->max_streams) { initparams.sinit_max_instreams = s->max_streams; initparams.sinit_num_ostreams = s->max_streams; - if (setsockopt(fd, SOL_SCTP, SCTP_INITMSG, &initparams, + if (setsockopt(fd, IPPROTO_SCTP, SCTP_INITMSG, &initparams, sizeof(initparams)) < 0) av_log(h, AV_LOG_ERROR, "SCTP ERROR: Unable to initialize socket max streams %d\n", |