AMF

From Gnash Project Wiki

Jump to: navigation, search

Contents

AMF Format

The AMF format is used in the LocalConnection, SharedObject, NetConnection, and NetStream ActionScript classes. This is a means of binary data interchange between Flash movies, or between a Flash player and a Flash server.

Like the RTMP messages, an AMF packet header can be of a variable size. The size is either the same as the initial header of the RTMP message, or a 1 byte header, which is commonly used for streaming audio or video data.

The body of an AMF packet may look something like this example. The spaces have been added for clarity.

02 0007 636f6e6e656374
  • 02
This is a single byte header. It specifies the content type of the following data (see table below).
  • 0007
This is the length in bytes of the string (big endian)
  • 63 6f 6e 6e 65 63 74
This is the string. Note that there is no null terminator since the length is specified.

Data Types

AMF0 supports the following data types (with their type field values):

  • NUMBER = 0x00
  • BOOLEAN = 0x01
  • STRING = 0x02
  • OBJECT = 0x03
  • MOVIECLIP = 0x04
  • NULL_VALUE = 0x05
  • UNDEFINED = 0x06
  • REFERENCE = 0x07
  • ECMA_ARRAY = 0x08
  • OBJECT_END = 0x09
  • STRICT_ARRAY = 0x0a
  • DATE = 0x0b
  • LONG_STRING = 0x0c
  • UNSUPPORTED = 0x0d
  • RECORD_SET = 0x0e
  • XML_OBJECT = 0x0f
  • TYPED_OBJECT = 0x10

Binary Format

AMF format for a value/object consists of a type byte (see above) followed by zero or more bytes. This section describes the bytes following the type byte for various types.

NUMBER (type byte: 0x00)

Numbers are stored as 8 byte (big endian) float double. On x86 you can just byteswap a double to encode it correctly.

BOOLEAN (type byte: 0x01)

A boolean is encoded in one byte. FIXME: is true sent as 0xff? 0x01?

STRING (type byte: 0x02)

A string is encoded as a 2 byte (big endian) count (number of bytes) followed by that many bytes of text. Note: there is no null terminator.

I think the text is assumed to be UTF-8. Can someone double check me on this? -- JasonWoof 00:44, 31 July 2008 (MDT)

NULL_VALUE (type byte: 0x05)

A null has zero bytes following the type byte

UNDEFINED (type byte: 0x06)

A undefined has zero bytes following the type byte

OBJECT (type byte: 0x08)

An object is encoded as a series of key/value pairs. The key is encoded as a STRING (above) WITH NO TYPE BYTE, and the value is any AMF value.

The object encoding is terminated by 0x000009 (that is a zero length string key, followed by the OBJECT_END type byte described below.

OBJECT_END (type byte: 0x09)

This is not really a value, but a marker for the end of an OBJECT. See above.

STRICT_ARRAY (type byte: 0x0a)

This is the encoding for arrays such as ["foo", "bar", 1, 2, 3]. For a hash (a set of key/value pairs) you'll need to use OBJECT above.

An array is encoded as 4 byte (big endian) integer which is the number of elements in the array, followed by that many AMF values.

That's it. There's no terminator of any kind.

Use in shared object files

While most AMF objects are just a value, there is a special variation used by shared object files for properties. Rather than start with the type field, followed by the length, it starts with a byte count, then the name, and then the regular AMF type field, the length, and then the data.

Use by NetConnection::call()

NetConnection::call() uses the AMF encoding for it's parameters and return values for/from the remote call(s).

The first two bytes of an AMF packet header are the AMF type, which should be 0x0 for AMF0, or 0x11 for AMF3. Following the type field, are two 16 bit header fields, the first one is the count of how many headers are in the packet (often 0), and the second is the count of messages in the packet.

Each message also has it's own header. The first field is a string that is the header field. This string is proceeded by a two byte length field for the string. This is followed by another length field and string. This second string is the operation name for the remote call. This is a / followed by a number used to keep things synchronized. The message header is finished by a 4 byte value that is the total number of bytes in the rest of the message. The data then follows.

Hex Chart

All numbers in AMF0 are big-endian, doubles, which are 8 bytes long. To make recognizing the basic numbers used the several ID numbers uses in AMF objects, here is a chart of Doubles, as decoded into the proper raw bytes. This makes it easier to recognize these numbers when staring at hex dumps.

Gnash Internals

All of the code Gnash uses to handle AMF objects is in the gnash/libamf directory. The Element class is used to hold an AMF object in it's decoded form. This class is used for all other manipulation. The AMF class handles all the encoding and decoding of binary AMF objects. The SOL class is used to manipulate AMF objects when using them with shared objects, and the LcShm class is used to manipulate AMF objects when using them with LocalConnection. Finally, the RTMP class is the network protocol used for streaming, which also uses AMF objects.