[FFmpeg-soc] [soc]: r4764 - in rtmp: rtmppkt.c rtmppkt.h rtmpproto.c
kostya
subversion at mplayerhq.hu
Wed Jul 22 08:16:45 CEST 2009
Author: kostya
Date: Wed Jul 22 08:16:45 2009
New Revision: 4764
Log:
Use typed functions for writing AMF data instead of one untyped function and
use AMF type definitions from flv.h instead of cloned ones in rtmppkt.h
Modified:
rtmp/rtmppkt.c
rtmp/rtmppkt.h
rtmp/rtmpproto.c
Modified: rtmp/rtmppkt.c
==============================================================================
--- rtmp/rtmppkt.c Wed Jul 22 08:12:36 2009 (r4763)
+++ rtmp/rtmppkt.c Wed Jul 22 08:16:45 2009 (r4764)
@@ -27,30 +27,47 @@
#include "avformat.h"
#include "rtmppkt.h"
+#include "flv.h"
-void ff_amf_write_tag(uint8_t **dst, AMFType type, const void *data)
+void ff_amf_write_bool(uint8_t **dst, int val)
{
- if (type != AMF_OBJECT_END && type != AMF_STRING_IN_OBJECT)
- bytestream_put_byte(dst, type);
- switch(type){
- case AMF_NUMBER:
- bytestream_put_be64(dst, av_dbl2int(*(const double*)data));
- break;
- case AMF_BOOLEAN:
- bytestream_put_byte(dst, *(const uint8_t*)data);
- break;
- case AMF_STRING:
- case AMF_STRING_IN_OBJECT:
- bytestream_put_be16(dst, strlen(data));
- bytestream_put_buffer(dst, data, strlen(data));
- break;
- case AMF_OBJECT_END:
- bytestream_put_be24(dst, AMF_OBJECT_END);
- break;
- case AMF_STRICT_ARRAY:
- bytestream_put_be32(dst, *(const uint32_t*)data);
- break;
- }
+ bytestream_put_byte(dst, AMF_DATA_TYPE_BOOL);
+ bytestream_put_byte(dst, val);
+}
+
+void ff_amf_write_number(uint8_t **dst, double val)
+{
+ bytestream_put_byte(dst, AMF_DATA_TYPE_NUMBER);
+ bytestream_put_be64(dst, av_dbl2int(val));
+}
+
+void ff_amf_write_string(uint8_t **dst, const char *str)
+{
+ bytestream_put_byte(dst, AMF_DATA_TYPE_STRING);
+ bytestream_put_be16(dst, strlen(str));
+ bytestream_put_buffer(dst, str, strlen(str));
+}
+
+void ff_amf_write_null(uint8_t **dst)
+{
+ bytestream_put_byte(dst, AMF_DATA_TYPE_NULL);
+}
+
+void ff_amf_write_object_start(uint8_t **dst)
+{
+ bytestream_put_byte(dst, AMF_DATA_TYPE_OBJECT);
+}
+
+void ff_amf_write_field_name(uint8_t **dst, const char *str)
+{
+ bytestream_put_be16(dst, strlen(str));
+ bytestream_put_buffer(dst, str, strlen(str));
+}
+
+void ff_amf_write_object_end(uint8_t **dst)
+{
+ // first two bytes are field name length = 0, AMF object should end with it and end marker
+ bytestream_put_be24(dst, AMF_DATA_TYPE_OBJECT_END);
}
int ff_rtmp_packet_read(URLContext *h, RTMPPacket *p,
@@ -178,14 +195,14 @@ int ff_amf_skip_data(const uint8_t *data
const uint8_t *base = data;
switch (*data++) {
- case AMF_NUMBER: return 9;
- case AMF_BOOLEAN: return 2;
- case AMF_STRING: return 3 + AV_RB16(data);
- case AMF_LONG_STRING: return 5 + AV_RB32(data);
- case AMF_NULL: return 1;
- case AMF_ECMA_ARRAY:
+ case AMF_DATA_TYPE_NUMBER: return 9;
+ case AMF_DATA_TYPE_BOOL: return 2;
+ case AMF_DATA_TYPE_STRING: return 3 + AV_RB16(data);
+ case AMF_DATA_TYPE_LONG_STRING: return 5 + AV_RB32(data);
+ case AMF_DATA_TYPE_NULL: return 1;
+ case AMF_DATA_TYPE_ARRAY:
data += 4;
- case AMF_OBJECT:
+ case AMF_DATA_TYPE_OBJECT:
for (;;) {
int size = bytestream_get_be16(&data);
if (!size) {
@@ -196,7 +213,7 @@ int ff_amf_skip_data(const uint8_t *data
data += ff_amf_skip_data(data);
}
return data - base;
- case AMF_OBJECT_END: return 1;
+ case AMF_DATA_TYPE_OBJECT_END: return 1;
default: return -1;
}
}
@@ -207,7 +224,7 @@ int ff_amf_find_field(const uint8_t *dat
int namelen = strlen(name);
int len;
- if (*data++ != AMF_OBJECT)
+ if (*data++ != AMF_DATA_TYPE_OBJECT)
return -1;
for (;;) {
int size = bytestream_get_be16(&data);
@@ -216,13 +233,13 @@ int ff_amf_find_field(const uint8_t *dat
data += size;
if (size == namelen && !memcmp(data-size, name, namelen)) {
switch (*data++) {
- case AMF_NUMBER:
+ case AMF_DATA_TYPE_NUMBER:
snprintf(dst, dst_size, "%g", av_int2dbl(AV_RB64(data)));
return 0;
- case AMF_BOOLEAN:
+ case AMF_DATA_TYPE_BOOL:
snprintf(dst, dst_size, "%s", *data ? "true" : "false");
return 0;
- case AMF_STRING:
+ case AMF_DATA_TYPE_STRING:
len = bytestream_get_be16(&data);
av_strlcpy(dst, data, FFMIN(len+1, dst_size));
return 0;
Modified: rtmp/rtmppkt.h
==============================================================================
--- rtmp/rtmppkt.h Wed Jul 22 08:12:36 2009 (r4763)
+++ rtmp/rtmppkt.h Wed Jul 22 08:16:45 2009 (r4764)
@@ -69,31 +69,6 @@ enum RTMPPacketSize {
};
/**
- * AMF types used in RTMP packets
- */
-typedef enum AMFType {
- AMF_NUMBER = 0, ///< number (double precision)
- AMF_BOOLEAN, ///< boolean value
- AMF_STRING, ///< Pascal-style string with length < 65536
- AMF_OBJECT, ///< AMF object, contains property names and values
- AMF_MOVIE, ///< Flash object
- AMF_NULL, ///< NULL value
- AMF_UNDEFINED, ///< undefined (return?) value
- AMF_REFERENCE, ///< reference
- AMF_ECMA_ARRAY, ///< ECMA array, almost like AMF object but has number of entries
- AMF_OBJECT_END, ///< marker for end of AMF object or ECMA array
- AMF_STRICT_ARRAY, ///< strict array
- AMF_DATE, ///< date
- AMF_LONG_STRING, ///< Pascal-style string with possible length up to 4GB
- AMF_UNSUPPORTED, ///< unsipported feature indicator
- AMD_RECORD_SET, ///< record set
- AMF_XML_OBJECT, ///< XML object
- AMF_TYPED_OBJECT, ///< typed object
-
- AMF_STRING_IN_OBJECT = 99, ///< internal type used for AMF object field names
-} AMFType;
-
-/**
* structure for holding RTMP packets
*/
typedef struct RTMPPacket {
@@ -178,13 +153,57 @@ int ff_amf_find_field(const uint8_t *dat
uint8_t *dst, int dst_size);
/**
- * Write AMF tag to buffer.
+ * Write boolean value in AMF format to buffer.
*
- * @param dst pointer to the input buffer (will be modified)
- * @param type tag type
- * @param data optional tag value
+ * @param dst pointer to the input buffer (will be modified)
+ * @param val value to write
*/
-void ff_amf_write_tag(uint8_t **dst, AMFType type, const void *data);
+void ff_amf_write_bool(uint8_t **dst, int val);
+
+/**
+ * Write number in AMF format to buffer.
+ *
+ * @param dst pointer to the input buffer (will be modified)
+ * @param num value to write
+ */
+void ff_amf_write_number(uint8_t **dst, double num);
+
+/**
+ * Write string in AMF format to buffer.
+ *
+ * @param dst pointer to the input buffer (will be modified)
+ * @param str string to write
+ */
+void ff_amf_write_string(uint8_t **dst, const char *str);
+
+/**
+ * Write AMF NULL value to buffer.
+ *
+ * @param dst pointer to the input buffer (will be modified)
+ */
+void ff_amf_write_null(uint8_t **dst);
+
+/**
+ * Write marker for AMF object to buffer.
+ *
+ * @param dst pointer to the input buffer (will be modified)
+ */
+void ff_amf_write_object_start(uint8_t **dst);
+
+/**
+ * Write string used as field name in AMF object to buffer.
+ *
+ * @param dst pointer to the input buffer (will be modified)
+ * @param str string to write
+ */
+void ff_amf_write_field_name(uint8_t **dst, const char *str);
+
+/**
+ * Write marker for end of AMF object to buffer.
+ *
+ * @param dst pointer to the input buffer (will be modified)
+ */
+void ff_amf_write_object_end(uint8_t **dst);
/** @} */ // AMF funcs
Modified: rtmp/rtmpproto.c
==============================================================================
--- rtmp/rtmpproto.c Wed Jul 22 08:12:36 2009 (r4763)
+++ rtmp/rtmpproto.c Wed Jul 22 08:16:45 2009 (r4764)
@@ -95,41 +95,34 @@ static void gen_connect(URLContext *s, R
RTMPPacket pkt;
uint8_t ver[32], *p;
char tcurl[512];
- double num = 1.0;
- uint8_t bool;
ff_rtmp_packet_create(&pkt, RTMP_VIDEO_CHANNEL, RTMP_PT_INVOKE, 0, 4096);
p = pkt.data;
snprintf(tcurl, sizeof(tcurl), "%s://%s:%d/%s", proto, host, port, app);
- ff_amf_write_tag(&p, AMF_STRING, "connect");
- ff_amf_write_tag(&p, AMF_NUMBER, &num);
- ff_amf_write_tag(&p, AMF_OBJECT, NULL);
- ff_amf_write_tag(&p, AMF_STRING_IN_OBJECT, "app");
- ff_amf_write_tag(&p, AMF_STRING, app);
+ ff_amf_write_string(&p, "connect");
+ ff_amf_write_number(&p, 1.0);
+ ff_amf_write_object_start(&p);
+ ff_amf_write_field_name(&p, "app");
+ ff_amf_write_string(&p, app);
snprintf(ver, sizeof(ver), "%s %d,%d,%d,%d", RTMP_CLIENT_PLATFORM, RTMP_CLIENT_VER1,
RTMP_CLIENT_VER2, RTMP_CLIENT_VER3, RTMP_CLIENT_VER4);
- ff_amf_write_tag(&p, AMF_STRING_IN_OBJECT, "flashVer");
- ff_amf_write_tag(&p, AMF_STRING, ver);
- ff_amf_write_tag(&p, AMF_STRING_IN_OBJECT, "tcUrl");
- ff_amf_write_tag(&p, AMF_STRING, tcurl);
- bool = 0;
- ff_amf_write_tag(&p, AMF_STRING_IN_OBJECT, "fpad");
- ff_amf_write_tag(&p, AMF_NUMBER, &bool);
- num = 15.0;
- ff_amf_write_tag(&p, AMF_STRING_IN_OBJECT, "capabilities");
- ff_amf_write_tag(&p, AMF_NUMBER, &num);
- num = 1639.0;
- ff_amf_write_tag(&p, AMF_STRING_IN_OBJECT, "audioCodecs");
- ff_amf_write_tag(&p, AMF_NUMBER, &num);
- num = 252.0;
- ff_amf_write_tag(&p, AMF_STRING_IN_OBJECT, "videoCodecs");
- ff_amf_write_tag(&p, AMF_NUMBER, &num);
- num = 1.0;
- ff_amf_write_tag(&p, AMF_STRING_IN_OBJECT, "videoFunction");
- ff_amf_write_tag(&p, AMF_NUMBER, &num);
- ff_amf_write_tag(&p, AMF_OBJECT_END, NULL);
+ ff_amf_write_field_name(&p, "flashVer");
+ ff_amf_write_string(&p, ver);
+ ff_amf_write_field_name(&p, "tcUrl");
+ ff_amf_write_string(&p, tcurl);
+ ff_amf_write_field_name(&p, "fpad");
+ ff_amf_write_bool(&p, 0);
+ ff_amf_write_field_name(&p, "capabilities");
+ ff_amf_write_number(&p, 15.0);
+ ff_amf_write_field_name(&p, "audioCodecs");
+ ff_amf_write_number(&p, 1639.0);
+ ff_amf_write_field_name(&p, "videoCodecs");
+ ff_amf_write_number(&p, 252.0);
+ ff_amf_write_field_name(&p, "videoFunction");
+ ff_amf_write_number(&p, 1.0);
+ ff_amf_write_object_end(&p);
pkt.data_size = p - pkt.data;
@@ -140,16 +133,14 @@ static void gen_create_stream(URLContext
{
RTMPPacket pkt;
uint8_t *p;
- double num;
//av_log(s, AV_LOG_DEBUG, "Creating stream...\n");
ff_rtmp_packet_create(&pkt, RTMP_VIDEO_CHANNEL, RTMP_PT_INVOKE, 0, 25);
- num = 3.0;
p = pkt.data;
- ff_amf_write_tag(&p, AMF_STRING, "createStream");
- ff_amf_write_tag(&p, AMF_NUMBER, &num);
- ff_amf_write_tag(&p, AMF_NULL, NULL);
+ ff_amf_write_string(&p, "createStream");
+ ff_amf_write_number(&p, 3.0);
+ ff_amf_write_null(&p);
ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
ff_rtmp_packet_destroy(&pkt);
@@ -159,21 +150,18 @@ static void gen_play(URLContext *s, RTMP
{
RTMPPacket pkt;
uint8_t *p;
- double num;
//av_log(s, AV_LOG_DEBUG, "Sending play command for '%s'\n", rt->playpath);
ff_rtmp_packet_create(&pkt, RTMP_VIDEO_CHANNEL, RTMP_PT_INVOKE, 0,
29 + strlen(rt->playpath));
pkt.extra = rt->main_channel_id;
- num = 0.0;
p = pkt.data;
- ff_amf_write_tag(&p, AMF_STRING, "play");
- ff_amf_write_tag(&p, AMF_NUMBER, &num);
- ff_amf_write_tag(&p, AMF_NULL, NULL);
- ff_amf_write_tag(&p, AMF_STRING, rt->playpath);
- num = 0.0;
- ff_amf_write_tag(&p, AMF_NUMBER, &num);
+ ff_amf_write_string(&p, "play");
+ ff_amf_write_number(&p, 0.0);
+ ff_amf_write_null(&p);
+ ff_amf_write_string(&p, rt->playpath);
+ ff_amf_write_number(&p, 0.0);
ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
ff_rtmp_packet_destroy(&pkt);
More information about the FFmpeg-soc
mailing list