[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