Hi Reimar D?ffinger wrote: > Hello, > another little update. > On Sat, Jan 13, 2007 at 06:24:30PM +0100, Michael Niedermayer wrote: >> On Sat, Jan 13, 2007 at 02:13:37PM +0100, Reimar D?ffinger wrote: > [...] >>> The key in AVFormatParameters is supposed to be a string for easier >>> extensibility and easy way to specify on commandline mostly. >> iam unhappy with this, what about per stream keys? and why not simply >> pass a uint8_t array? also i hate AVFormatParameters why not use >> AVFormatContext ? > > Per stream keys: I'd like to ignore for now, they could be handled via > AVStream, but > 1) there also needs to be a way to associate keys to > streams, so e.g. the key ID would have to be exported, too > 2) A key somewhere else would probably still be needed, since it would > not work for formats where either already the header parsing function > needs a key and not work well for formats where AVStreams are added > during playback. > But I moved it to AVFormatContext in binary format with additional > keylen field. > > Updated patch also should finally really fix seeking for encrypted > files. > >>> The current format is just a hex string like "02045a...", 32 characters for >>> AES-128 (the only format supported currently). >>> IMO openssl should be replaced, it is too bloated for such a simple >>> functionality but I'm not yet sure by what, not to mention that I am not >>> up to date if it still has such an inconvenient license... >> <random bloated crpto lib> dependance for just AES is completely unacceptable >> write your own 2 page implementation of AES > > It also uses now my aes128 code, which can also be switched to libgcrypt > for whoever needs that final bit of speed our code does not yet provide. > > Greetings, > Reimar D?ffinger > > > ------------------------------------------------------------------------ > > Index: libavformat/avformat.h > =================================================================== > --- libavformat/avformat.h (revision 7475) > +++ libavformat/avformat.h (working copy) > @@ -25,8 +25,8 @@ > extern "C" { > #endif > > -#define LIBAVFORMAT_VERSION_INT ((51<<16)+(7<<8)+0) > -#define LIBAVFORMAT_VERSION 51.7.0 > +#define LIBAVFORMAT_VERSION_INT ((51<<16)+(8<<8)+0) > +#define LIBAVFORMAT_VERSION 51.8.0 > #define LIBAVFORMAT_BUILD LIBAVFORMAT_VERSION_INT > > #define LIBAVFORMAT_IDENT "Lavf" AV_STRINGIFY(LIBAVFORMAT_VERSION) > @@ -361,6 +352,8 @@ > int loop_input; > /* decoding: size of data to probe; encoding unused */ > unsigned int probesize; > + const char *key; > + int keylen; > } AVFormatContext; Why not uint8_t * ? > [...[ > @@ -141,7 +166,9 @@ > UID content_storage_uid; > MXFMetadataSet **metadata_sets; > int metadata_sets_count; > + UID *sync_key; > AVFormatContext *fc; Should not sync_key be uint8_t * ? > typedef struct KLVPacket { > @@ -174,6 +201,9 @@ > /* partial keys to match */ > static const uint8_t mxf_header_partition_pack_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02 }; > static const uint8_t mxf_essence_element_key[] = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01 }; > +/* complete keys to match */ > +static const uint8_t mxf_encrypted_triplet_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x04,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x7e,0x01,0x00 }; > +static const uint8_t mxf_encrypted_essence_container[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x0b,0x01,0x00 }; > > #define IS_KLV_KEY(x, y) (!memcmp(x, y, sizeof(y))) > > @@ -207,6 +237,8 @@ > { > int i; > > + if (!IS_KLV_KEY(klv->key, mxf_essence_element_key)) > + return -1; > for (i = 0; i < s->nb_streams; i++) { > MXFTrack *track = s->streams[i]->priv_data; > /* SMPTE 379M 7.3 */ > @@ -225,8 +257,7 @@ Why is that hunk needed ? dont call get_stream_index if key is not mxf_essence_element_key > if (length > 61444) /* worst case PAL 1920 samples 8 channels */ > return -1; > - get_buffer(pb, buffer, length); > - av_new_packet(pkt, length); > + memcpy(buffer, pkt->data, length); > data_ptr = pkt->data; > end_ptr = buffer + length; > buf_ptr = buffer + 4; /* skip SMPTE 331M header */ > @@ -246,11 +277,58 @@ > return 0; > } > > [...] > > + > static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt) > { > KLVPacket klv; > > while (!url_feof(&s->pb)) { > + int encrypted = 0; > if (klv_read_packet(&klv, &s->pb) < 0) { > av_log(s, AV_LOG_ERROR, "error reading KLV packet\n"); > return -1; > @@ -258,21 +336,29 @@ > #ifdef DEBUG > PRINT_KEY("read packet", klv.key); > #endif > + if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key)) { > + int res = mxf_decrypt_triplet(s, pkt, &klv); > + if (res < 0) { > + av_log(s, AV_LOG_ERROR, "invalid encoded triplet\n"); > + continue; > + } > + encrypted = 1; > + } > if (IS_KLV_KEY(klv.key, mxf_essence_element_key)) { > int index = mxf_get_stream_index(s, &klv); > if (index < 0) { > av_log(s, AV_LOG_ERROR, "error getting stream index\n"); > - url_fskip(&s->pb, klv.length); > return -1; > } > + if (!encrypted) > + av_get_packet(&s->pb, pkt, klv.length); > /* check for 8 channels AES3 element */ > if (klv.key[12] == 0x06 && klv.key[13] == 0x01 && klv.key[14] == 0x10) { > if (mxf_get_d10_aes3_packet(&s->pb, s->streams[index], pkt, klv.length) < 0) { > av_log(s, AV_LOG_ERROR, "error reading D-10 aes3 frame\n"); > return -1; > } > - } else > - av_get_packet(&s->pb, pkt, klv.length); > + } > pkt->stream_index = index; > return 0; > } else > @@ -562,6 +648,43 @@ > MXF_READ_LOCAL_TAGS_STOP(Descriptor, MXFDescriptor, descriptor) > } I would prefer calling mxf_get_stream_index from klv_decrypt_triplet, and avoid using that encrypted var in the mail loop. Also avoid one useless memcpy for unencrypted files and d10_aes3 stream and that code should be to an AVBitstreamFilter anyway. > [...] > > static int mxf_parse_structural_metadata(MXFContext *mxf) > { > MXFPackage *material_package = NULL; > @@ -679,6 +823,7 @@ > const MXFCodecUL *codec_ul = NULL; > const MXFCodecUL *container_ul = NULL; > AVStream *st; > + UID *essence_container_ul; > > if (!(material_track = mxf_resolve_strong_ref(mxf, &material_package->tracks_refs[i], Track))) { > av_log(mxf->fc, AV_LOG_ERROR, "could not resolve material track strong ref\n"); > @@ -768,9 +913,16 @@ > av_log(mxf->fc, AV_LOG_INFO, "source track %d: stream %d, no descriptor found\n", source_track->track_id, st->index); > continue; > } > + essence_container_ul = descriptor->essence_container_ul; > + if (IS_KLV_KEY(essence_container_ul, mxf_encrypted_essence_container)) { > + MXFCryptoContext *cc = mxf_find_track_cryptocontext(mxf, descriptor->linked_track_id); > + if (cc) > + essence_container_ul = cc->source_ul; > + mxf->sync_key = mxf_encrypted_triplet_key; > + } That's wrong. descriptor essence container should be original source coutainer. That file is broken. Working 100% solution must be implemented, also linked track id is optional in S377M. Yes it is complicated but a working 100% solution exists. > [...] > > @@ -856,6 +1011,8 @@ > MXFContext *mxf = s->priv_data; > KLVPacket klv; > > + mxf->aesc = aes128_init(); Init must be optional of course. > if (!mxf_read_sync(&s->pb, mxf_header_partition_pack_key, 14)) { > av_log(s, AV_LOG_ERROR, "could not find header partition pack key\n"); > return -1; > @@ -872,7 +1029,8 @@ > #ifdef DEBUG > PRINT_KEY("read header", klv.key); > #endif > - if (IS_KLV_KEY(klv.key, mxf_essence_element_key)) { > + if (IS_KLV_KEY(klv.key, mxf_essence_element_key) || > + IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key)) { > /* FIXME avoid seek */ > url_fseek(&s->pb, klv.offset, SEEK_SET); > break; We could use header size in partition pack and stop if end is reached. That should avoid seek and check for keys. > [...] > > @@ -942,6 +1104,7 @@ > /* XXX: use MXF Index */ > static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags) > { > + MXFContext *mxf = s->priv_data; > AVStream *st = s->streams[stream_index]; > int64_t seconds; > > @@ -951,7 +1114,7 @@ > sample_time = 0; > seconds = av_rescale(sample_time, st->time_base.num, st->time_base.den); > url_fseek(&s->pb, (s->bit_rate * seconds) >> 3, SEEK_SET); > - if (!mxf_read_sync(&s->pb, mxf_essence_element_key, 12)) > + if (!mxf_read_sync(&s->pb, mxf->sync_key, 12)) > return -1; > > /* found KLV key */ > Seek hunk looks ok. -- Baptiste COUDURIER GnuPG Key Id: 0x5C1ABAAA SMARTJOG S.A. http://www.smartjog.com Key fingerprint 8D77134D20CC9220201FC5DB0AC9325C5C1ABAAA Phone: +33 1 49966312
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4