On 25/06/14 12:16, Alexandra Hájková wrote:
> The tool prints out asf file structure.
> ---
> libavformat/Makefile | 3 +-
> tools/asfinfo.c | 533
> +++++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 535 insertions(+), 1 deletion(-)
> create mode 100644 tools/asfinfo.c
>
> diff --git a/libavformat/Makefile b/libavformat/Makefile
> index a7f03f9..76bb9b5 100644
> --- a/libavformat/Makefile
> +++ b/libavformat/Makefile
> @@ -402,7 +402,8 @@ TESTPROGS = seek
> \
>
> TESTPROGS-$(CONFIG_NETWORK) += noproxy
>
> -TOOLS = aviocat \
> +TOOLS = asfinfo \
> + aviocat \
> ismindex \
> pktdumper \
> probetest \
> diff --git a/tools/asfinfo.c b/tools/asfinfo.c
> new file mode 100644
> index 0000000..14d0d6d
> --- /dev/null
> +++ b/tools/asfinfo.c
> @@ -0,0 +1,533 @@
> +/*
> + * Copyright (c) 2014 Alexandra Hajkova
> + *
> + * This file is part of Libav.
> + *
> + * Libav is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * Libav is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with Libav; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
> USA
> + */
> +
> +#include "config.h"
> +
> +#include <ctype.h>
> +#include <errno.h>
> +#include <limits.h>
> +#include <math.h>
> +#include <signal.h>
> +#include <stdint.h>
> +#include <stdlib.h>
> +#include <string.h>
> +
> +#include "libavutil/avstring.h"
> +
> +#include "libavformat/asf.h"
> +#include "libavformat/avformat.h"
> +
> +#define ASF_TYPE_AUDIO 0x2
> +#define ASF_TYPE_VIDEO 0x1
> +#define ASF_STREAM_NUM 0x7F
> +#define ASF_ERROR_CORRECTION_LENGTH_TYPE 0x60
> +#define ASF_NUM_OF_PAYLOADS 0x3F
> +
> +static const char *filename;
> +static const char program_name[] = "asfinfo";
> +static const int program_birth_year = 2014;
> +
> +static unsigned char GUID[16]; //128-bit
> +
> +typedef struct guids {
> + char name[100];
> + char num[16];
> + int (*read_object)(AVIOContext*, struct guids*, int64_t);
> +} guids;
> +
> +typedef struct data_properties {
> + uint64_t num_of_packets;
> + uint32_t packet_size;
> +} data_properties;
> +
> +static data_properties *datap = NULL;
> +
> +static void guidfix(unsigned char GUID[16])
> +{
> + unsigned char c;
> + c = GUID[0]; GUID[0] = GUID[3]; GUID[3] = c;
> + c = GUID[1]; GUID[1] = GUID[2]; GUID[2] = c;
> + c = GUID[4]; GUID[4] = GUID[5]; GUID[5] = c;
> + c = GUID[6]; GUID[6] = GUID[7]; GUID[7] = c;
> +}
> +
> +static void show_usage(void)
> +{
> + printf("ASF file format viewer\n");
> + printf("usage: %s input_file\n", program_name);
> + printf("\n");
> +}
> +
> +static void print_object_size(uint64_t size, char *info)
> +{
> + if (size)
> + printf("%s: %"PRIu64" bytes\n", info, size);
> + else
> + printf(" Error while reading object size\n");
> +}
> +
> +static uint64_t read_obj_size(AVIOContext *pb, guids *g, int64_t offset)
> +{
> + uint64_t size;
> + int ret = 0;
> +
> + if (g->name) {
> + if (!memcmp(g->name, "Header", 6) || !memcmp(g->name, "Data", 4) ||
> + !memcmp(g->name, "Index", 5) || !memcmp(g->name, "Simple
> Index", 12) ||
> + !memcmp(g->name, "Media Object Index", 18) || !memcmp(g->name,
> "Timecode Index", 14)) {
> + printf("ASF %s Object, position: %"PRId64" bytes\n", g->name,
> offset);
> + size = avio_rl64(pb);
> + print_object_size(size, " Object size");
> +
> + return size;
> + } else {
> + printf(" ASF %s Object, position: %"PRId64" bytes\n", g->name,
> offset);
> + size = avio_rl64(pb);
> + print_object_size(size, " Object size");
> +
> + return size;
> + }
> + } else
> + printf("Unknown object, position: %"PRId64" bytes\n", offset);
> + size = avio_rl64(pb);
> + print_object_size(size, " Object size");
> +
> + return size;
> +}
> +
> +static void check_position(AVIOContext *pb, int64_t offset, uint64_t size)
> +{
> +
> + if (avio_tell(pb) != (offset + size)) {
> + printf("Error! Expected position %"PRIu64", got %"PRIu64". Seeking
> to the expected postition.\n",
> + offset + size, avio_tell(pb));
> + avio_seek(pb, offset + size, SEEK_SET);
> + }
> +}
> +
> +static int read_header(AVIOContext *pb, guids *g, int64_t offset)
> +{
> + uint64_t size = read_obj_size(pb, g, offset);
> + avio_skip(pb, 6);
> +
> + return 0;
> +}
> +
> +static read_metadata(AVIOContext *pb, const char *title, uint16_t len,
> unsigned char *ch, uint16_t max_len)
> +{
> + printf(" %s: ", title);
> + memset(ch, 0, max_len);
> + avio_get_str16le(pb, len * sizeof(*ch), ch, len * sizeof(*ch));
> + printf(" %s\n", ch);
> +
> + return 0;
> +}
> +
> +static int read_content(AVIOContext *pb, guids *g, int64_t offset)
> +{
> + int i;
> + uint16_t len[5], max_len = 0;
> + const char *titles[] = { "Title", "Author", "Copyright", "Description",
> "Rate" };
> + unsigned char *ch;
> + uint64_t size = read_obj_size(pb, g, offset);
> +
> + for (i = 0; i < 5; i++) {
> + len[i] = avio_rl16(pb);
> + max_len = FFMAX(max_len, len[i]);
> + }
> + ch = av_mallocz(max_len * sizeof(*ch));
> + if (!ch)
> + return(AVERROR(ENOMEM));
> + for (i = 0; i < 5; i++)
> + read_metadata(pb, titles[i], len[i], ch, max_len);
> +
> + av_free(ch);
> + check_position(pb, offset, size);
> +
> + return 0;
> +}
> +
> +static int read_unknown(AVIOContext *pb, guids *g, int64_t offset)
> +{
> + uint64_t size = read_obj_size(pb, g, offset);
> +
> + avio_skip(pb, size - 24);
> +
> + return 0;
> +}
> +
> +// modified GET_STR16 from aviobuf
> +static int get_asf_unicode(AVIOContext *pb, int maxlen, char *buf, int
> buflen)
> +{
> + char* q = buf;
> + int ret = 0;
> + if (buflen <= 0)
> + return AVERROR(EINVAL);
> + while (ret + 1 < maxlen) {
> + uint8_t tmp;
> + uint32_t ch;
> + GET_UTF16(ch, (ret += 2) <= maxlen ? avio_rl16(pb) : 0, break;)
> + PUT_UTF8(ch, tmp, if (q - buf < buflen - 1) *q++ = tmp;)\
> + }
> + *q = 0;
> + return ret;
> +}
> +
> +static void read_unicode(AVIOContext *pb, char *info)
> +{
> + uint16_t len;
> + int ret;
> +
> + if (len = avio_rl16(pb)) {
> + unsigned char *name;
> + len *= 2; // len is number of unicode characters - 2 bytes for each
> char
> + name = av_mallocz(len);
> + if (!name)
> + return AVERROR(ENOMEM);
> + ret = get_asf_unicode(pb, len, name, len);
> + printf(" %s: %s\n", info, name);
> + av_free(name);
> + }
> +}
> +
> +static int read_codec_list(AVIOContext *pb, guids *g, int64_t offset)
> +{
> + int i, ret;
> + uint16_t len, type;
> + uint64_t size;
> + uint32_t n_codecs;
> +
> + size = read_obj_size(pb, g, offset);
> + avio_skip(pb, sizeof(GUID)); // skip field reserved for guid
> + n_codecs = avio_rl32(pb);
> + for (i = 0; i < n_codecs; i++) {
> + type = avio_rl16(pb);
> + if (type == ASF_TYPE_VIDEO)
> + printf(" Codec type: Video codec\n");
> + else if (type == ASF_TYPE_AUDIO)
> + printf(" Codec type: Audio codec\n");
> + else
> + printf(" Codec type: Unknown codec\n");
> + read_unicode(pb, "Codec name");
> + read_unicode(pb, "Codec description");
> + if (len = avio_rl16(pb)) {
> + unsigned char *in;
> + in = av_mallocz(len);
> + if (!in)
> + return AVERROR(ENOMEM);
> + ret = avio_read(pb, in, len);
> + printf(" Codec information: %02X\n", in);
> + av_free(in);
> + }
> + }
> + check_position(pb, offset, size);
> +
> + return 0;
> +}
> +
> +static int read_properties(AVIOContext *pb, guids *g, int64_t offset)
> +{
> + uint64_t size, num_of_packets;
> + uint32_t flags, min_packet_size, max_packet_size, max_bitrate;
> +
> + size = read_obj_size(pb, g, offset);
> + avio_skip(pb, 16); // skip File ID
> + size = avio_rl64(pb); //File size
> + avio_skip(pb, 8); // skip creation date
> + num_of_packets = avio_rl64(pb);
> + avio_skip(pb, 24); //skip play and send duration, preroll
> + flags = avio_rl32(pb);
> + min_packet_size = avio_rl32(pb);
> + max_packet_size = avio_rl32(pb);
> + max_bitrate = avio_rl32(pb);
> + printf(" File size %"PRId64", number of packets %"PRId64", min packet
> size %"PRId32", max packet size %"PRId32", max bitrate %"PRId32"\n",
> + size, num_of_packets, min_packet_size, max_packet_size,
> max_bitrate);
> + datap->num_of_packets = num_of_packets;
> + datap->packet_size = max_packet_size;
> +
> + return 0;
> +}
> +
> +#define read_length(flag, name, len) \
> + do { \
> + if (flag == name ## IS_BYTE) \
> + len = avio_r8(pb); \
> + else if (flag == name ## IS_WORD) \
> + len = avio_rl16(pb); \
> + else if (flag == name ## IS_DWORD) \
> + len = avio_rl32(pb); \
> + else \
> + len = 0; \
> + } while(0)
> +
> +static void read_subpayload(AVIOContext *pb, int64_t offset, uint32_t
> pad_len, int mult_payload)
> +{
> + unsigned char sub_len;
> + uint16_t len;
> + int64_t sub_offset, sub;
> +
> + printf(" Sub-Payloads present.\n");
> + avio_skip(pb, 1); // skip presentation time delta
> + if (mult_payload)
> + len = avio_rl16(pb); // total
> + sub = avio_tell(pb);
> + do {
> + sub_len = avio_r8(pb);
> + sub_offset = avio_tell(pb);
> + printf(" Sub-Payload at position %"PRIu64" of length %d\n",
> + sub_offset, sub_len);
> + avio_skip(pb, sub_len);
> + if (mult_payload && (avio_tell(pb) >= (sub + len)))
> + break;
> + } while (sub_offset < (offset + datap->packet_size - pad_len));
> + if (!mult_payload)
> + avio_skip(pb, pad_len);
> +}
> +
> +static int read_payload(AVIOContext *pb, int64_t offset, unsigned char flags,
> + int multiple_payload, uint32_t pad_len)
> +{
> + unsigned char stream_num;
> + uint64_t size, off2;
> + uint32_t rep_len, off_len, media_len;
> + uint16_t pay_len;
> + int sub_offset;
> +
> + stream_num = avio_r8(pb);
> + stream_num &= ASF_STREAM_NUM;
> + read_length((flags & ASF_PL_MASK_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_SIZE),
> + ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_, media_len);
> + read_length((flags &
> ASF_PL_MASK_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_SIZE),
> + ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_,
> off_len);
> + read_length((flags & ASF_PL_MASK_REPLICATED_DATA_LENGTH_FIELD_SIZE),
> + ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_, rep_len);
> + if (multiple_payload) {
> + if (rep_len == 1)
> + read_subpayload(pb, offset, pad_len, 1);
> + else {
> + avio_skip(pb, rep_len); // skip replicated data
> + pay_len = avio_rl16(pb); // payload length should be WORD
> + off2 = avio_tell(pb);
> + printf(" packet for stream #%d of size %"PRIu64" at position
> %"PRId64"\n",
> + stream_num, pay_len, off2);
> + if (pay_len > datap->packet_size) {
> + printf(" Error: invalid data packet size.\n");
> + av_free(datap);
> + return AVERROR_INVALIDDATA;
> + }
> + avio_skip(pb, pay_len);
> + }
> + } else if (rep_len == 1) {
> + read_subpayload(pb, offset, pad_len, 0);
> + } else {
> + off2 = avio_tell(pb);
> + // packet size without header, can cointain replicated data or
> presentaion time delta before payload
> + // and padding after it
> + size = datap->packet_size - off2 + offset;
> + if (size > datap->packet_size) {
> + printf(" Error: invalid data packet size %"PRIu64" bytes.\n",
> size);
> + av_free(datap);
> + return AVERROR_INVALIDDATA;
> + }
> + printf(" packet for stream #%d of size %"PRIu64" at position
> %"PRId64"\n", stream_num, size, off2);
> + avio_skip(pb, size); // skip payload
> + }
> + return 0;
> +}
> +
> +static int read_data(AVIOContext *pb, guids *g, int64_t offset)
> +{
> + int ret, i, off2, off3;
> + uint64_t size;
> + uint32_t packet_len, seq, pad_len, pts;
> + uint16_t duration;
> + unsigned char GUID[16], error_flags, len_flags, pay_flags,
> property_flags;
> +
> + size = read_obj_size(pb, g, offset);
> + ret = avio_read(pb, GUID, sizeof(GUID));
> + if (ret) {
> + printf(" File ID ");
> + for (i = 0; i < 16; i++)
> + printf("%1.2X", GUID[i]);
> + }
> + printf("\n");
> + size = avio_rl64(pb);
> + printf(" Number of Data packets %"PRIu64"\n", size);
> + avio_skip(pb, 2); // skip reserved field
> + for (i = 0; i < datap->num_of_packets; i++) {
> + offset = avio_tell(pb);
> + error_flags = avio_r8(pb); // read Error Correction Flags
> + if (error_flags & ASF_PACKET_FLAG_ERROR_CORRECTION_PRESENT)
> + if (!(error_flags & ASF_ERROR_CORRECTION_LENGTH_TYPE)) {
> + size = error_flags & ASF_PACKET_ERROR_CORRECTION_DATA_SIZE;
> + avio_skip(pb, size);
> + }
> + len_flags = avio_r8(pb);
> + property_flags = avio_r8(pb);
> + read_length((len_flags & ASF_PPI_MASK_PACKET_LENGTH_FIELD_SIZE),
> + ASF_PPI_FLAG_PACKET_LENGTH_FIELD_, packet_len);
> + read_length((len_flags & ASF_PPI_MASK_SEQUENCE_FIELD_SIZE),
> + ASF_PPI_FLAG_SEQUENCE_FIELD_, seq);
> + read_length((len_flags & ASF_PPI_MASK_PADDING_LENGTH_FIELD_SIZE),
> + ASF_PPI_FLAG_PADDING_LENGTH_FIELD_, pad_len );
> + pts = avio_rl32(pb);
> + duration = avio_rl16(pb);
> + off2 = avio_tell(pb);
> + if (len_flags & ASF_PPI_FLAG_MULTIPLE_PAYLOADS_PRESENT) { //
> Multiple Payloads present
> + int j, num; // number of payloads
> + pay_flags = avio_r8(pb);
> + num = pay_flags & ASF_NUM_OF_PAYLOADS;
> + printf("Multiple payload at one packet present: %d payloads\n",
> num);
> + for (j = 0; j < num; j++)
> + if ((ret = read_payload(pb, offset, property_flags, 1,
> pad_len)) < 0)
> + return ret;
> + avio_skip(pb, pad_len);
> + } else
> + if ((ret = read_payload(pb, offset, property_flags, 0, pad_len))
> < 0)
> + return ret;
> + }
> + return 0;
> +}
> +
> +const guids gdef[] = {
> + {"Header", {0x75, 0xB2, 0x26, 0x30, 0x66, 0x8E,
> 0x11, 0xCF, 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C}, read_header},
> + {"Data", {0x75, 0xB2, 0x26, 0x36, 0x66, 0x8E,
> 0x11, 0xCF, 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C}, read_data},
> + {"Simple Index", {0x33, 0x00, 0x08, 0x90, 0xE5, 0xB1,
> 0x11, 0xCF, 0x89, 0xF4, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xCB}, read_unknown},
> + {"Content Description", {0x75, 0xB2, 0x26, 0x33, 0x66 ,0x8E,
> 0x11, 0xCF, 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C}, read_content},
> + {"Extended Content Description", {0xD2, 0xD0, 0xA4, 0x40, 0xE3, 0x07,
> 0x11, 0xD2, 0x97, 0xF0, 0x00, 0xA0, 0xC9, 0x5e, 0xA8, 0x50}, read_unknown},
> + {"Stream Bitrate Properties", {0x7B, 0xF8, 0x75, 0xCE, 0x46, 0x8D,
> 0x11, 0xD1, 0x8D, 0x82, 0x00, 0x60, 0x97, 0xC9, 0xA2, 0xB2}, read_unknown},
> + {"File Properties", {0x8C, 0xAB, 0xDC, 0xA1, 0xA9, 0x47,
> 0x11, 0xCF, 0x8E, 0xE4, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65}, read_properties},
> + {"Header Extension", {0x5F, 0xBF, 0x03, 0xB5, 0xA9, 0x2E,
> 0x11, 0xCF, 0x8E, 0xE3, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65}, read_unknown},
> + {"Stream Properties", {0xB7, 0xDC, 0x07, 0x91, 0xA9, 0xB7,
> 0x11, 0xCF, 0x8E, 0xE6, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65}, read_unknown},
> + {"Codec List", {0x86, 0xD1, 0x52, 0x40, 0x31, 0x1D,
> 0x11, 0xD0, 0xA3, 0xA4, 0x00, 0xA0, 0xC9, 0x03, 0x48, 0xF6}, read_codec_list},
> + {"Marker", {0xF4, 0x87, 0xCD, 0x01, 0xA9, 0x51,
> 0x11, 0xCF, 0x8E, 0xE6, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65}, read_unknown},
> + {"Script Command", {0x1E, 0xFB, 0x1A, 0x30, 0x0B, 0x62,
> 0x11, 0xD0, 0xA3, 0x9B, 0x00, 0xA0, 0xC9, 0x03, 0x48, 0xF6}, read_unknown},
> + {"Language List", {0x7C, 0x43, 0x46, 0xa9, 0xef, 0xe0,
> 0x4B, 0xFC, 0xB2, 0x29, 0x39, 0x3e, 0xde, 0x41, 0x5c, 0x85}, read_unknown},
> + {"Padding", {0x18, 0x06, 0xD4, 0x74, 0xCA, 0xDF,
> 0x45, 0x09, 0xA4, 0xBA, 0x9A, 0xAB, 0xCB, 0x96, 0xAA, 0xE8}, read_unknown},
> + {"DRMv1 Header", {0x22, 0x11, 0xB3, 0xFB, 0xBD, 0x23,
> 0x11, 0xD2, 0xB4, 0xB7, 0x00, 0xA0, 0xC9, 0x55, 0xFC, 0x6E}, read_unknown},
> + {"DRMv2 Header", {0x29, 0x8A, 0xE6, 0x14, 0x26, 0x22,
> 0x4C, 0x17, 0xB9, 0x35, 0xDA, 0xE0, 0x7E, 0xE9, 0x28, 0x9c}, read_unknown},
> + {"Index", {0xD6, 0xE2, 0x29, 0xD3, 0x35, 0xDA,
> 0x11, 0xD1, 0x90, 0x34, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xBE}, read_unknown},
> + {"Media Object Index", {0xFE, 0xB1, 0x03, 0xF8, 0x12, 0xAD,
> 0x4C, 0x64, 0x84, 0x0F, 0x2A, 0x1D, 0x2F, 0x7A, 0xD4, 0x8C}, read_unknown},
> + {"Timecode Index", {0x3C, 0xB7, 0x3F, 0xD0, 0x0C, 0x4A,
> 0x48, 0x03, 0x95, 0x3D, 0xED, 0xF7, 0xB6, 0x22, 0x8F, 0x0C}, read_unknown},
> + {"Bitrate_Mutual_Exclusion", {0xD6, 0xE2, 0x29, 0xDC, 0x35, 0xDA,
> 0x11, 0xD1, 0x90, 0x34, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xBE}, read_unknown},
> + {"Error Correction", {0x75, 0xB2, 0x26, 0x35, 0x66, 0x8E,
> 0x11, 0xCF, 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C}, read_unknown},
> + {"Content Branding", {0x22, 0x11, 0xB3, 0xFA, 0xBD, 0x23,
> 0x11, 0xD2, 0xB4, 0xB7, 0x00, 0xA0, 0xC9, 0x55, 0xFC, 0x6E}, read_unknown},
> + {"Content Encryption", {0x22, 0x11, 0xB3, 0xFB, 0xBD, 0x23,
> 0x11, 0xD2, 0xB4, 0xB7, 0x00, 0xA0, 0xC9, 0x55, 0xFC, 0x6E}, read_unknown},
> + {"Extended Content Encryption", {0x29, 0x8A, 0xE6, 0x14, 0x26, 0x22,
> 0x4C, 0x17, 0xB9, 0x35, 0xDA, 0xE0, 0x7E, 0xE9, 0x28, 0x9C}, read_unknown},
> + {"Digital Signature", {0x22, 0x11, 0xB3, 0xFC, 0xBD, 0x23,
> 0x11, 0xD2, 0xB4, 0xB7, 0x00, 0xA0, 0xC9, 0x55, 0xFC, 0x6E}, read_unknown},
> + {"Extended Stream Properties", {0x14, 0xE6, 0xA5, 0xCB, 0xC6, 0x72,
> 0x43, 0x32, 0x83, 0x99, 0xA9, 0x69, 0x52, 0x06, 0x5B, 0x5A}, read_unknown},
> + {"Advanced Mutual Exclusion", {0xA0, 0x86, 0x49, 0xCF, 0x47, 0x75,
> 0x46, 0x70, 0x8A, 0x16, 0x6E, 0x35, 0x35, 0x75, 0x66, 0xCD}, read_unknown},
> + {"Group Mutual Exclusion", {0xD1, 0x46, 0x5A, 0x40, 0x5A, 0x79,
> 0x43, 0x38, 0xB7, 0x1B, 0xE3, 0x6B, 0x8F, 0xD6, 0xC2, 0x49}, read_unknown},
> + {"Stream Prioritization", {0xD4, 0xFE, 0xD1, 0x5B, 0x88, 0xD3,
> 0x45, 0x4F, 0x81, 0xF0, 0xED, 0x5C, 0x45, 0x99, 0x9E, 0x24}, read_unknown},
> + {"Bandwidth Sharing Object", {0xA6, 0x96, 0x09, 0xE6, 0x51, 0x7B,
> 0x11, 0xD2, 0xB6, 0xAF, 0x00, 0xC0, 0x4F, 0xD9, 0x08, 0xE9}, read_unknown},
> + {"Metadata", {0xC5, 0xF8, 0xCB, 0xEA, 0x5B, 0xAF,
> 0x48, 0x77, 0x84, 0x67, 0xAA, 0x8C, 0x44, 0xFA, 0x4C, 0xCA}, read_unknown},
> + {"Audio Spread", {0xBF, 0xC3, 0xCD, 0x50, 0x61, 0x8F,
> 0x11, 0xCF, 0x8B, 0xB2, 0x00, 0xAA, 0x00, 0xB4, 0xE2, 0x20}, read_unknown},
> + {"Content Encryption System Windows Media DRM Network Devices",
> + {0x7A, 0x07, 0x9B, 0xB6, 0xDA, 0XA4,
> 0x4e, 0x12, 0xA5, 0xCA, 0x91, 0xD3, 0x8D, 0xC1, 0x1A, 0x8D}, read_unknown},
> + {"Mutex Language", {0xD6, 0xE2, 0x2A, 0x00, 0x25, 0xDA,
> 0x11, 0xD1, 0x90, 0x34, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xBE}, read_unknown},
> + {"Mutex Bitrate", {0xD6, 0xE2, 0x2A, 0x01, 0x25, 0xDA,
> 0x11, 0xD1, 0x90, 0x34, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xBE}, read_unknown},
> + {"Mutex Unknown", {0xD6, 0xE2, 0x2A, 0x02, 0x25, 0xDA,
> 0x11, 0xD1, 0x90, 0x34, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xBE}, read_unknown},
> + {"Bandwith Sharing Exclusive", {0xAF, 0x60, 0x60, 0xAA, 0x51, 0x97,
> 0x11, 0xD2, 0xB6, 0xAF, 0x00, 0xC0, 0x4F, 0xD9, 0x08, 0xE9}, read_unknown},
> + {"Bandwith Sharing Partial", {0xAF, 0x60, 0x60, 0xAB, 0x51, 0x97,
> 0x11, 0xD2, 0xB6, 0xAF, 0x00, 0xC0, 0x4F, 0xD9, 0x08, 0xE9}, read_unknown},
> + {"Payload Extension System Timecode", {0x39, 0x95, 0x95, 0xEC, 0x86,
> 0x67, 0x4E, 0x2D, 0x8F, 0xDB, 0x98, 0x81, 0x4C, 0xE7, 0x6C, 0x1E},
> read_unknown},
> + {"Payload Extension System File Name", {0xE1, 0x65, 0xEC, 0x0E, 0x19,
> 0xED, 0x45, 0xD7, 0xB4, 0xA7, 0x25, 0xCB, 0xD1, 0xE2, 0x8E, 0x9B},
> read_unknown},
> + {"Payload Extension System Content Type", {0xD5, 0x90, 0xDC, 0x20, 0x07,
> 0xBC, 0x43, 0x6C, 0x9C, 0xF7, 0xF3, 0xBB, 0xFB, 0xF1, 0xA4, 0xDC},
> read_unknown},
> + {"Payload Extension System Pixel Aspect Ratio", {0x1, 0x1E, 0xE5, 0x54,
> 0xF9, 0xEA, 0x4B, 0xC8, 0x82, 0x1A, 0x37, 0x6B, 0x74, 0xE4, 0xC4, 0xB8},
> read_unknown},
> + {"Payload Extension System Sample Duration", {0xC6, 0xBD, 0x94, 0x50,
> 0x86, 0x7F, 0x49, 0x07, 0x83, 0xA3, 0xC7, 0x79, 0x21, 0xB7, 0x33, 0xAD},
> read_unknown},
> + {"Payload Extension System Encryption Sample ID", {0x66, 0x98, 0xB8,
> 0x4E, 0x0A, 0xFA, 0x43, 0x30, 0xAE, 0xB2, 0x1C, 0x0A, 0x98, 0xD7, 0xA4,
> 0x4D}, read_unknown},
> + {"Payload Extension System Degradable JPEG", {0x00, 0xE1, 0xAF, 0x06,
> 0x7B, 0xEC, 0x11, 0xD1, 0xA5, 0x82, 0x00, 0xC0, 0x4F, 0xC2, 0x9C, 0xFB},
> read_unknown},
> +
> +};
> +
> +static guids *find_guid(unsigned char *guid, guids *g)
> +{
> + int j, ret;
> +
> + g = gdef;
> + for (j = 0; j < FF_ARRAY_ELEMS(g->num); j++) {
> + if (!(ret = memcmp(guid, g->num, sizeof(g->num))))
> + return g;
> + g++;
> + }
> + return NULL;
> +}
> +
> +int main(int argc, char **argv)
> +{
> + AVIOContext *pb;
> + guids *g = NULL;
> + unsigned char GUID[16], GUID2[16];
> + char *buf;
> + int ret, i;
> + int64_t offset, off2, off3;
> +
> + filename = argv[1];
> + if (!filename) {
> + show_usage();
> + fprintf(stderr, "An input file must be specified\n");
> + exit(1);
> + }
> + av_register_all();
> + buf = av_mallocz(16 * sizeof(*buf));
Is it used?
> + if (!buf)
> + return AVERROR(ENOMEM);
> + if ((ret = avio_open(&pb, filename, AVIO_FLAG_READ)) < 0) {
> + av_log(NULL, AV_LOG_ERROR, "%s\n", filename);
> + avio_close(pb);
> + exit(1);
> + }
> + datap = av_mallocz(sizeof(*datap));
> + if (!datap)
> + return AVERROR(ENOMEM);
> + while (1) {
> + offset = avio_tell(pb);
> + //printf("position of the object: %d bytes\n", offset);
> + if (ret = avio_read(pb, GUID, sizeof(GUID)) < 0) {
> + if (ret == AVERROR(EOF))
> + break;
> + if (ret < 0) {
> + printf("error\n");
Print the error here.
> + continue;
> + }
> + }
> + memcpy(GUID2, GUID, 16);
> + guidfix(GUID);
> + g = find_guid(GUID, g);
> + if (g) {
> + for (i = 0; i < 16; i++)
> + printf("%1.2X", GUID2[i]);
> + printf("\n");
> + if ((ret = g->read_object(pb, g, offset)) < 0) {
> + av_free(datap);
> + av_free(buf);
> + avio_close(pb);
> + return ret;
> + }
> + }
> + }
> + for (i = 0; i < 16; i++)
> + printf("%1.2X", GUID2[i]);
> + printf("\n");
> + printf("position %d\n", avio_tell(pb));
> + av_free(datap);
> + av_free(buf);
> + avio_close(pb);
> + return 0;
> +}
The rest seems fine.
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel