We are using Parrot’s libvideo-metadata library to parse parrot metadata in our media player. Currently we are running into problems parsing metadata in protobuf format from Anafi AI. There is a file (vmeta.proto) that contains the protobuf schema for all the parrot metadata structures. This schema must be “compiled” into C code (vmeta.pb-c.h) so the protobuf C library can pack/unpack to/from C structs. This vmeta.pb-c.h file is included by vmeta_frame_proto.h but the file itself is not in the libvideo-metadata repo. We tried to generate vmeta.pb-c.h ourselves from vmeta.proto using the “protoc” command line program from GitHub - protobuf-c/protobuf-c: Protocol Buffers implementation in C. However when we try to unpack a metadata frame from Anafi AI with vmeta_frame_read(), we get a segfault in vmeta__timed_metadata__unpack() in vmeta.pb-c.h due to a mismatch between the protobuf C struct size and the vmeta buffer length.*
Question 1: We are getting the metadata buffer from the RTP packet header extension. Are we correct to assume the metadata buffer length is equal to the RTP packet header extension length? This appears to be true for V1/V2/V3 frame formats (we can parse these successfully), but possibly not protobuf format?*
Question 2: Could we get a working version of vmeta.pb-c.h (along with the git commit it was generated for)? In case the program we’re using to generate it is the problem.*
Regards,
David Geisler Geisler@rapidimagingtech.com
Question 1: We are getting the metadata buffer from the RTP packet header extension. Are we correct to assume the metadata buffer length is equal to the RTP packet header extension length? This appears to be true for V1/V2/V3 frame formats (we can parse these successfully), but possibly not protobuf format?
The packing format for protobuf is a little bit more complex than that, since the size of a packet is not constant. You can find our packing/unpacking code in libvideo-streaming, our library that handles this in the SDK, but here is a quick description of the format:
The metadata buffer can be split into multiple RTP headers over a single frame (on the N firsts RTP packets). Each RTP header extension contains the following data (all fields except the raw data are in network endian):
A metadata type identifier (2 bytes) : 0x5062 (“Pb” in ascii)
A raw data length indicator (2 bytes), number of 4 bytes groups of data in the payload
A pack number/total indicator (2 bytes) : described in vstrm_rtp_h264.h. If the “current” packet index is equal to the “last” packet index, then this is the last packet for the frame, and the metadata buffer will be complete
An offset (in bytes) to store the raw data in the metadata buffer (2 bytes)
The raw data of the metadata packet
To rebuild the metadata buffer, you can follow this pseudocode:
// Assuming buffer[] is big enough for the frame,
// and network/host endianness is properly handled
foreach RTP_packet {
ext = get_header_ext(RTP_packet)
memcpy(&buffer[ext.offset], ext.raw_data, 4*ext.len);
// We should also check that every pack was received at least once
if (ext.pack.current == ext.pack.last)
metadata_is_done(buffer)
}
Question 2: Could we get a working version of vmeta.pb-c.h (along with the git commit it was generated for)? In case the program we’re using to generate it is the problem.
Due to my response to your first question, I’m pretty sure that the vmeta.pb-c.[h/c] you generated is fine (we indeed use protobuf-c, as you’ve guessed), and that the content of the metadata buffer was the issue, but I will attach to this message the generated files from the latest GitHub commit (f9a267974cdc5d3e7d118ead0dff8d9180c1425e) so you can compare them to the one you generated: