Merge commit '64f8c439fd663fec4d57ac21af572d498fe21f7a'
authorHendrik Leppkes <h.leppkes@gmail.com>
Fri, 1 Jan 2016 16:21:32 +0000 (17:21 +0100)
committerHendrik Leppkes <h.leppkes@gmail.com>
Fri, 1 Jan 2016 16:21:32 +0000 (17:21 +0100)
* commit '64f8c439fd663fec4d57ac21af572d498fe21f7a':
  rtmpproto: Include the full path as app when "slist=" is found

Merged-by: Hendrik Leppkes <h.leppkes@gmail.com>
1  2 
libavformat/rtmpproto.c

diff --combined libavformat/rtmpproto.c
@@@ -2,20 -2,20 +2,20 @@@
   * RTMP network protocol
   * Copyright (c) 2009 Konstantin Shishkov
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * FFmpeg is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
 - * Libav is distributed in the hope that it will be useful,
 + * FFmpeg is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
 - * License along with Libav; if not, write to the Free Software
 + * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  
@@@ -48,9 -48,9 +48,9 @@@
  #include <zlib.h>
  #endif
  
 -#define APP_MAX_LENGTH 128
 -#define PLAYPATH_MAX_LENGTH 256
 -#define TCURL_MAX_LENGTH 512
 +#define APP_MAX_LENGTH 1024
 +#define PLAYPATH_MAX_LENGTH 512
 +#define TCURL_MAX_LENGTH 1024
  #define FLASHVER_MAX_LENGTH 64
  #define RTMP_PKTDATA_DEFAULT_SIZE 4096
  #define RTMP_HEADER 11
@@@ -217,8 -217,9 +217,8 @@@ static void free_tracked_methods(RTMPCo
      int i;
  
      for (i = 0; i < rt->nb_tracked_methods; i ++)
 -        av_free(rt->tracked_methods[i].name);
 -    av_free(rt->tracked_methods);
 -    rt->tracked_methods      = NULL;
 +        av_freep(&rt->tracked_methods[i].name);
 +    av_freep(&rt->tracked_methods);
      rt->tracked_methods_size = 0;
      rt->nb_tracked_methods   = 0;
  }
@@@ -321,7 -322,7 +321,7 @@@ static int gen_connect(URLContext *s, R
      int ret;
  
      if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
 -                                     0, 4096)) < 0)
 +                                     0, 4096 + APP_MAX_LENGTH)) < 0)
          return ret;
  
      p = pkt.data;
@@@ -418,7 -419,6 +418,7 @@@ static int read_connect(URLContext *s, 
      if (pkt.type == RTMP_PT_CHUNK_SIZE) {
          if ((ret = handle_chunk_size(s, &pkt)) < 0)
              return ret;
 +
          ff_rtmp_packet_destroy(&pkt);
          if ((ret = ff_rtmp_packet_read(rt->stream, &pkt, rt->in_chunk_size,
                                         &rt->prev_pkt[0], &rt->nb_prev_pkt[0])) < 0)
@@@ -1748,23 -1748,18 +1748,23 @@@ static int handle_connect_error(URLCont
          char *value = strchr(ptr, '=');
          if (next)
              *next++ = '\0';
 -        if (value)
 +        if (value) {
              *value++ = '\0';
 -        if (!strcmp(ptr, "user")) {
 -            user = value;
 -        } else if (!strcmp(ptr, "salt")) {
 -            salt = value;
 -        } else if (!strcmp(ptr, "opaque")) {
 -            opaque = value;
 -        } else if (!strcmp(ptr, "challenge")) {
 -            challenge = value;
 -        } else if (!strcmp(ptr, "nonce")) {
 -            nonce = value;
 +            if (!strcmp(ptr, "user")) {
 +                user = value;
 +            } else if (!strcmp(ptr, "salt")) {
 +                salt = value;
 +            } else if (!strcmp(ptr, "opaque")) {
 +                opaque = value;
 +            } else if (!strcmp(ptr, "challenge")) {
 +                challenge = value;
 +            } else if (!strcmp(ptr, "nonce")) {
 +                nonce = value;
 +            } else {
 +                av_log(s, AV_LOG_INFO, "Ignoring unsupported var %s\n", ptr);
 +            }
 +        } else {
 +            av_log(s, AV_LOG_WARNING, "Variable %s has NULL value\n", ptr);
          }
          ptr = next;
      }
@@@ -2416,7 -2411,7 +2416,7 @@@ static int get_packet(URLContext *s, in
          rt->last_timestamp = rpkt.timestamp;
  
          rt->bytes_read += ret;
 -        if (rt->bytes_read > rt->last_bytes_read + rt->client_report_size) {
 +        if (rt->bytes_read - rt->last_bytes_read > rt->client_report_size) {
              av_log(s, AV_LOG_DEBUG, "Sending bytes read report\n");
              if ((ret = gen_bytes_read(s, rt, rpkt.timestamp + 1)) < 0)
                  return ret;
@@@ -2533,7 -2528,7 +2533,7 @@@ static int inject_fake_duration_metadat
      // Increase the size by the injected packet
      rt->flv_size += 55;
      // Delete the old FLV data
 -    av_free(old_flv_data);
 +    av_freep(&old_flv_data);
  
      p = rt->flv_data + 13;
      bytestream_put_byte(&p, FLV_TAG_TYPE_META);
@@@ -2578,7 -2573,7 +2578,7 @@@ static int rtmp_open(URLContext *s, con
  {
      RTMPContext *rt = s->priv_data;
      char proto[8], hostname[256], path[1024], auth[100], *fname;
 -    char *old_app, *qmark, fname_buffer[1024];
 +    char *old_app, *qmark, *n, fname_buffer[1024];
      uint8_t buf[2048];
      int port;
      AVDictionary *opts = NULL;
                   hostname, sizeof(hostname), &port,
                   path, sizeof(path), s->filename);
  
 -    if (strchr(path, ' ')) {
 +    n = strchr(path, ' ');
 +    if (n) {
          av_log(s, AV_LOG_WARNING,
                 "Detected librtmp style URL parameters, these aren't supported "
                 "by the libavformat internal RTMP handler currently enabled. "
                 "See the documentation for the correct way to pass parameters.\n");
 +        *n = '\0'; // Trim not supported part
      }
  
      if (auth[0]) {
@@@ -2681,8 -2674,8 +2681,8 @@@ reconnect
      qmark = strchr(path, '?');
      if (qmark && strstr(qmark, "slist=")) {
          char* amp;
-         // After slist we have the playpath, before the params, the app
-         av_strlcpy(rt->app, path + 1, FFMIN(qmark - path, APP_MAX_LENGTH));
+         // After slist we have the playpath, the full path is used as app
+         av_strlcpy(rt->app, path + 1, APP_MAX_LENGTH);
          fname = strstr(path, "slist=") + 6;
          // Strip any further query parameters from fname
          amp = strchr(fname, '&');
          char *next = *path ? path + 1 : path;
          char *p = strchr(next, '/');
          if (!p) {
 -            fname = next;
 -            rt->app[0] = '\0';
 +            if (old_app) {
 +                // If name of application has been defined by the user, assume that
 +                // playpath is provided in the URL
 +                fname = next;
 +            } else {
 +                fname = NULL;
 +                av_strlcpy(rt->app, next, APP_MAX_LENGTH);
 +            }
          } else {
              // make sure we do not mismatch a playpath for an application instance
              char *c = strchr(p + 1, ':');
  
      if (old_app) {
          // The name of application has been defined by the user, override it.
 +        if (strlen(old_app) >= APP_MAX_LENGTH) {
 +            ret = AVERROR(EINVAL);
 +            goto fail;
 +        }
          av_free(rt->app);
          rt->app = old_app;
      }
  
      if (!rt->playpath) {
 -        int len = strlen(fname);
 -
          rt->playpath = av_malloc(PLAYPATH_MAX_LENGTH);
          if (!rt->playpath) {
              ret = AVERROR(ENOMEM);
              goto fail;
          }
  
 -        if (!strchr(fname, ':') && len >= 4 &&
 -            (!strcmp(fname + len - 4, ".f4v") ||
 -             !strcmp(fname + len - 4, ".mp4"))) {
 -            memcpy(rt->playpath, "mp4:", 5);
 +        if (fname) {
 +            int len = strlen(fname);
 +            if (!strchr(fname, ':') && len >= 4 &&
 +                (!strcmp(fname + len - 4, ".f4v") ||
 +                 !strcmp(fname + len - 4, ".mp4"))) {
 +                memcpy(rt->playpath, "mp4:", 5);
 +            } else {
 +                if (len >= 4 && !strcmp(fname + len - 4, ".flv"))
 +                    fname[len - 4] = '\0';
 +                rt->playpath[0] = 0;
 +            }
 +            av_strlcat(rt->playpath, fname, PLAYPATH_MAX_LENGTH);
          } else {
 -            if (len >= 4 && !strcmp(fname + len - 4, ".flv"))
 -                fname[len - 4] = '\0';
 -            rt->playpath[0] = 0;
 +            rt->playpath[0] = '\0';
          }
 -        av_strlcat(rt->playpath, fname, PLAYPATH_MAX_LENGTH);
      }
  
      if (!rt->tcurl) {
@@@ -2953,7 -2933,6 +2953,7 @@@ static int rtmp_write(URLContext *s, co
          if (rt->flv_header_bytes < RTMP_HEADER) {
              const uint8_t *header = rt->flv_header;
              int channel = RTMP_AUDIO_CHANNEL;
 +
              copy = FFMIN(RTMP_HEADER - rt->flv_header_bytes, size_temp);
              bytestream_get_buffer(&buf_temp, rt->flv_header + rt->flv_header_bytes, copy);
              rt->flv_header_bytes += copy;