comparison mxf.c @ 2945:670945e9899d libavformat

support dynamically allocated local tags, used by encrypted files
author bcoudurier
date Sat, 19 Jan 2008 16:17:39 +0000
parents 74bcc1d2eabb
children f90a2a21d5f6
comparison
equal deleted inserted replaced
2944:74bcc1d2eabb 2945:670945e9899d
138 int packages_count; 138 int packages_count;
139 MXFMetadataSet **metadata_sets; 139 MXFMetadataSet **metadata_sets;
140 int metadata_sets_count; 140 int metadata_sets_count;
141 AVFormatContext *fc; 141 AVFormatContext *fc;
142 struct AVAES *aesc; 142 struct AVAES *aesc;
143 uint8_t *local_tags;
144 int local_tags_count;
143 } MXFContext; 145 } MXFContext;
144 146
145 typedef struct { 147 typedef struct {
146 UID key; 148 UID key;
147 offset_t offset; 149 offset_t offset;
175 /* partial keys to match */ 177 /* partial keys to match */
176 static const uint8_t mxf_header_partition_pack_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02 }; 178 static const uint8_t mxf_header_partition_pack_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02 };
177 static const uint8_t mxf_essence_element_key[] = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01 }; 179 static const uint8_t mxf_essence_element_key[] = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01 };
178 static const uint8_t mxf_klv_key[] = { 0x06,0x0e,0x2b,0x34 }; 180 static const uint8_t mxf_klv_key[] = { 0x06,0x0e,0x2b,0x34 };
179 /* complete keys to match */ 181 /* complete keys to match */
182 static const uint8_t mxf_crypto_context_uid[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x09,0x01,0x01,0x15,0x11,0x00,0x00,0x00,0x00 };
183 static const uint8_t mxf_crypto_source_container_ul[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x09,0x06,0x01,0x01,0x02,0x02,0x00,0x00,0x00 };
180 static const uint8_t mxf_encrypted_triplet_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x04,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x7e,0x01,0x00 }; 184 static const uint8_t mxf_encrypted_triplet_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x04,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x7e,0x01,0x00 };
181 static const uint8_t mxf_encrypted_essence_container[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x0b,0x01,0x00 }; 185 static const uint8_t mxf_encrypted_essence_container[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x0b,0x01,0x00 };
182 186
183 #define IS_KLV_KEY(x, y) (!memcmp(x, y, sizeof(y))) 187 #define IS_KLV_KEY(x, y) (!memcmp(x, y, sizeof(y)))
184 188
365 url_fskip(s->pb, klv.length); 369 url_fskip(s->pb, klv.length);
366 } 370 }
367 return AVERROR(EIO); 371 return AVERROR(EIO);
368 } 372 }
369 373
374 static int mxf_read_primer_pack(MXFContext *mxf)
375 {
376 ByteIOContext *pb = mxf->fc->pb;
377 int item_num = get_be32(pb);
378 int item_len = get_be32(pb);
379
380 if (item_len != 18) {
381 av_log(mxf->fc, AV_LOG_ERROR, "unsupported primer pack item length\n");
382 return -1;
383 }
384 if (item_num > UINT_MAX / item_len)
385 return -1;
386 mxf->local_tags_count = item_num;
387 mxf->local_tags = av_malloc(item_num*item_len);
388 if (!mxf->local_tags)
389 return -1;
390 get_buffer(pb, mxf->local_tags, item_num*item_len);
391 return 0;
392 }
393
370 static int mxf_add_metadata_set(MXFContext *mxf, void *metadata_set) 394 static int mxf_add_metadata_set(MXFContext *mxf, void *metadata_set)
371 { 395 {
372 mxf->metadata_sets = av_realloc(mxf->metadata_sets, (mxf->metadata_sets_count + 1) * sizeof(*mxf->metadata_sets)); 396 mxf->metadata_sets = av_realloc(mxf->metadata_sets, (mxf->metadata_sets_count + 1) * sizeof(*mxf->metadata_sets));
373 if (!mxf->metadata_sets) 397 if (!mxf->metadata_sets)
374 return -1; 398 return -1;
375 mxf->metadata_sets[mxf->metadata_sets_count] = metadata_set; 399 mxf->metadata_sets[mxf->metadata_sets_count] = metadata_set;
376 mxf->metadata_sets_count++; 400 mxf->metadata_sets_count++;
377 return 0; 401 return 0;
378 } 402 }
379 403
380 static int mxf_read_metadata_cryptographic_context(MXFCryptoContext *cryptocontext, ByteIOContext *pb, int tag) 404 static int mxf_read_metadata_cryptographic_context(MXFCryptoContext *cryptocontext, ByteIOContext *pb, int tag, int size, UID uid)
381 { 405 {
382 switch(tag) { 406 if (size != 16)
383 case 0xFFFE: 407 return -1;
408 if (IS_KLV_KEY(uid, mxf_crypto_context_uid))
384 get_buffer(pb, cryptocontext->context_uid, 16); 409 get_buffer(pb, cryptocontext->context_uid, 16);
385 break; 410 else if (IS_KLV_KEY(uid, mxf_crypto_source_container_ul))
386 case 0xFFFD:
387 get_buffer(pb, cryptocontext->source_container_ul, 16); 411 get_buffer(pb, cryptocontext->source_container_ul, 16);
388 break;
389 }
390 return 0; 412 return 0;
391 } 413 }
392 414
393 static int mxf_read_metadata_content_storage(MXFContext *mxf, ByteIOContext *pb, int tag) 415 static int mxf_read_metadata_content_storage(MXFContext *mxf, ByteIOContext *pb, int tag)
394 { 416 {
874 } 896 }
875 return 0; 897 return 0;
876 } 898 }
877 899
878 static const MXFMetadataReadTableEntry mxf_metadata_read_table[] = { 900 static const MXFMetadataReadTableEntry mxf_metadata_read_table[] = {
901 { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x05,0x01,0x00 }, mxf_read_primer_pack },
879 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x18,0x00 }, mxf_read_metadata_content_storage, 0, AnyType }, 902 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x18,0x00 }, mxf_read_metadata_content_storage, 0, AnyType },
880 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x37,0x00 }, mxf_read_metadata_source_package, sizeof(MXFPackage), SourcePackage }, 903 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x37,0x00 }, mxf_read_metadata_source_package, sizeof(MXFPackage), SourcePackage },
881 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x36,0x00 }, mxf_read_metadata_material_package, sizeof(MXFPackage), MaterialPackage }, 904 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x36,0x00 }, mxf_read_metadata_material_package, sizeof(MXFPackage), MaterialPackage },
882 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x0F,0x00 }, mxf_read_metadata_sequence, sizeof(MXFSequence), Sequence }, 905 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x0F,0x00 }, mxf_read_metadata_sequence, sizeof(MXFSequence), Sequence },
883 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x11,0x00 }, mxf_read_metadata_source_clip, sizeof(MXFStructuralComponent), SourceClip }, 906 { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x11,0x00 }, mxf_read_metadata_source_clip, sizeof(MXFStructuralComponent), SourceClip },
904 return -1; 927 return -1;
905 while (url_ftell(pb) + 4 < klv_end) { 928 while (url_ftell(pb) + 4 < klv_end) {
906 int tag = get_be16(pb); 929 int tag = get_be16(pb);
907 int size = get_be16(pb); /* KLV specified by 0x53 */ 930 int size = get_be16(pb); /* KLV specified by 0x53 */
908 uint64_t next= url_ftell(pb) + size; 931 uint64_t next= url_ftell(pb) + size;
932 UID uid;
909 933
910 if (!size) { /* ignore empty tag, needed for some files with empty UMID tag */ 934 if (!size) { /* ignore empty tag, needed for some files with empty UMID tag */
911 av_log(mxf->fc, AV_LOG_ERROR, "local tag 0x%04X with 0 size\n", tag); 935 av_log(mxf->fc, AV_LOG_ERROR, "local tag 0x%04X with 0 size\n", tag);
912 continue; 936 continue;
913 } 937 }
938 if (tag > 0x7FFF) { /* dynamic tag */
939 int i;
940 for (i = 0; i < mxf->local_tags_count; i++) {
941 int local_tag = AV_RB16(mxf->local_tags+i*18);
942 if (local_tag == tag) {
943 memcpy(uid, mxf->local_tags+i*18+2, 16);
944 dprintf(mxf->fc, "local tag 0x%04X\n", local_tag);
945 #ifdef DEBUG
946 PRINT_KEY(mxf->fc, "uid", uid);
947 #endif
948 }
949 }
950 }
914 if(ctx_size && tag == 0x3C0A) 951 if(ctx_size && tag == 0x3C0A)
915 get_buffer(pb, ctx->uid, 16); 952 get_buffer(pb, ctx->uid, 16);
916 else 953 else
917 read_child(ctx, pb, tag, size); 954 read_child(ctx, pb, tag, size, uid);
918 955
919 url_fseek(pb, next, SEEK_SET); 956 url_fseek(pb, next, SEEK_SET);
920 } 957 }
921 if (ctx_size) ctx->type = type; 958 if (ctx_size) ctx->type = type;
922 return ctx_size ? mxf_add_metadata_set(mxf, ctx) : 0; 959 return ctx_size ? mxf_add_metadata_set(mxf, ctx) : 0;
948 break; 985 break;
949 } 986 }
950 987
951 for (metadata = mxf_metadata_read_table; metadata->read; metadata++) { 988 for (metadata = mxf_metadata_read_table; metadata->read; metadata++) {
952 if (IS_KLV_KEY(klv.key, metadata->key)) { 989 if (IS_KLV_KEY(klv.key, metadata->key)) {
953 if (mxf_read_local_tags(mxf, &klv, metadata->read, metadata->ctx_size, metadata->type) < 0) { 990 int (*read)() = klv.key[5] == 0x53 ? mxf_read_local_tags : metadata->read;
991 if (read(mxf, &klv, metadata->read, metadata->ctx_size, metadata->type) < 0) {
954 av_log(s, AV_LOG_ERROR, "error reading header metadata\n"); 992 av_log(s, AV_LOG_ERROR, "error reading header metadata\n");
955 return -1; 993 return -1;
956 } 994 }
957 break; 995 break;
958 } 996 }
986 } 1024 }
987 av_freep(&mxf->metadata_sets[i]); 1025 av_freep(&mxf->metadata_sets[i]);
988 } 1026 }
989 av_freep(&mxf->metadata_sets); 1027 av_freep(&mxf->metadata_sets);
990 av_freep(&mxf->aesc); 1028 av_freep(&mxf->aesc);
1029 av_freep(&mxf->local_tags);
991 return 0; 1030 return 0;
992 } 1031 }
993 1032
994 static int mxf_probe(AVProbeData *p) { 1033 static int mxf_probe(AVProbeData *p) {
995 uint8_t *bufp = p->buf; 1034 uint8_t *bufp = p->buf;