On Sun, Apr 8, 2012 at 1:00 PM, Martin Storsjö <[email protected]> wrote:
> On Tue, 3 Apr 2012, Samuel Pitoiset wrote:
>
> Sometimes the URL parser cannot determine the app name automatically,
>> so it must be given explicitly using this option (ie. -app).
>> ---
>> libavformat/rtmpproto.c | 40 ++++++++++++++++++++++++++++++**+++++++++-
>> 1 file changed, 39 insertions(+), 1 deletion(-)
>>
>> diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c
>> index a6917ce..08bb86b 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
>> @@ -61,7 +64,7 @@ typedef struct RTMPContext {
>> 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
>> @@ -789,6 +792,7 @@ static int rtmp_close(URLContext *h)
>> gen_delete_stream(h, rt);
>>
>> av_freep(&rt->flv_data);
>> + av_free(rt->app);
>> ffurl_close(rt->stream);
>> return 0;
>> }
>>
>
> IIRC this shouldn't be needed, if you've declared it as an option, the
> normal option handling logic should free it (regardless if you've set it
> via an option or set by the protocol code itself).
>
>
Okay.
> @@ -806,6 +810,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;
>> @@ -831,6 +836,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) ? strdup(rt->app) : NULL;
>>
>
> Please use av_strdup instead of plain strdup (otherwise you can't use
> av_free to free it).
>
Done.
+
>> + 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;
>> @@ -852,6 +867,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;
>> + }
>> +
>>
>
> Hmm, this doesn't feel too nice, but I do see that we need to do the same
> parsing to find the playpath. Or should the full path be used as playpath
> if an app parameter is given? (How does rtmpdump/librtmp do it?)
librtmp has an option for the application name (ie. -app) and an other
option for the stream name (ie. playpath). So, I have to make a new patch
in order to introduce the option '-playpath'.
>
>
> if (!strchr(fname, ':') &&
>> (!strcmp(fname + strlen(fname) - 4, ".f4v") ||
>> !strcmp(fname + strlen(fname) - 4, ".mp4"))) {
>> @@ -997,6 +1019,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[] = {
>> + {"app", "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,
>> @@ -1005,4 +1042,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.9.4
>>
>
> If you add a private class, you need to add const AVClass *class; as the
> first member of the RTMPContext struct - the framework code will assume the
> first member is such a class pointer.
>
Okay.
> // Martin
>
> ______________________________**_________________
> libav-devel mailing list
> [email protected]
> https://lists.libav.org/**mailman/listinfo/libav-devel<https://lists.libav.org/mailman/listinfo/libav-devel>
>
--
Best regards,
Samuel Pitoiset.
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel