#include <time.h>
#include "libavutil/fifo.h"
+#include "libavutil/random_seed.h"
#include "libavcodec/bytestream.h"
#include "audiointerleave.h"
#include "avformat.h"
int timecode_drop_frame; ///< time code use drop frame method frop mpeg-2 essence gop header
int edit_unit_byte_count; ///< fixed edit unit byte count
uint64_t body_offset;
+ uint32_t instance_number;
+ uint8_t umid[16]; ///< unique material identifier
} MXFContext;
static const uint8_t uuid_base[] = { 0xAD,0xAB,0x44,0x24,0x2f,0x25,0x4d,0xc7,0x92,0xff,0x29,0xbd };
-static const uint8_t umid_base[] = { 0x06,0x0A,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x01,0x0D,0x00,0x13,0x00,0x00,0x00 };
+static const uint8_t umid_ul[] = { 0x06,0x0A,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x01,0x0D,0x00,0x13 };
/**
* complete key for operation pattern, partitions, and primer pack
put_be16(pb, value);
}
-static void mxf_write_umid(ByteIOContext *pb, enum MXFMetadataSetType type, int value)
+static void mxf_write_umid(AVFormatContext *s, int type)
{
- put_buffer(pb, umid_base, 16);
- mxf_write_uuid(pb, type, value);
+ MXFContext *mxf = s->priv_data;
+ put_buffer(s->pb, umid_ul, 13);
+ put_be24(s->pb, mxf->instance_number);
+ put_buffer(s->pb, mxf->umid, 15);
+ put_byte(s->pb, type);
}
static void mxf_write_refs_count(ByteIOContext *pb, int ref_count)
for (i = 0; i < 4; i++)
put_be64(pb, 0);
} else
- mxf_write_umid(pb, SourcePackage, 0);
+ mxf_write_umid(s, 1);
// write source track id
mxf_write_local_tag(pb, 4, 0x1102);
// write package umid
mxf_write_local_tag(pb, 32, 0x4401);
- mxf_write_umid(pb, type, 0);
+ mxf_write_umid(s, type == SourcePackage);
PRINT_KEY(s, "package umid second part", pb->buf_ptr - 16);
// package creation date
mxf_write_uuid(pb, EssenceContainerData, 0);
mxf_write_local_tag(pb, 32, 0x2701); // Linked Package UID
- mxf_write_umid(pb, SourcePackage, 0);
+ mxf_write_umid(s, 1);
mxf_write_local_tag(pb, 4, 0x3F07); // BodySID
put_be32(pb, 1);
// index edit rate
mxf_write_local_tag(pb, 8, 0x3F0B);
- put_be32(pb, mxf->time_base.num);
put_be32(pb, mxf->time_base.den);
+ put_be32(pb, mxf->time_base.num);
// index start position
mxf_write_local_tag(pb, 8, 0x3F0C);
static uint64_t mxf_parse_timestamp(time_t timestamp)
{
- struct tm *time = localtime(×tamp);
+ struct tm *time = gmtime(×tamp);
return (uint64_t)(time->tm_year+1900) << 48 |
(uint64_t)(time->tm_mon+1) << 40 |
(uint64_t) time->tm_mday << 32 |
time->tm_sec << 8;
}
+static void mxf_gen_umid(AVFormatContext *s)
+{
+ MXFContext *mxf = s->priv_data;
+ uint32_t seed = ff_random_get_seed();
+ uint64_t umid = seed + 0x5294713400000000LL;
+
+ AV_WB64(mxf->umid , umid);
+ AV_WB64(mxf->umid+8, umid>>8);
+
+ mxf->instance_number = seed;
+}
+
static int mxf_write_header(AVFormatContext *s)
{
MXFContext *mxf = s->priv_data;
uint8_t present[FF_ARRAY_ELEMS(mxf_essence_container_uls)] = {0};
const int *samples_per_frame = NULL;
+ if (!s->nb_streams)
+ return -1;
+
for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i];
MXFStreamContext *sc = av_mallocz(sizeof(*sc));
mxf->essence_container_count = 1;
}
+ if (!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT))
+ mxf_gen_umid(s);
+
for (i = 0; i < s->nb_streams; i++) {
MXFStreamContext *sc = s->streams[i]->priv_data;
// update element count
sc->order = AV_RB32(sc->track_essence_element_key+12);
}
- mxf->timestamp = mxf_parse_timestamp(s->timestamp);
+ if (s->timestamp)
+ mxf->timestamp = mxf_parse_timestamp(s->timestamp);
mxf->duration = -1;
mxf->timecode_track = av_mallocz(sizeof(*mxf->timecode_track));
klv_encode_ber4_length(pb, 35);
put_byte(pb, 0x83); // UMID
put_be16(pb, 0x20);
- mxf_write_umid(pb, SourcePackage, 0);
+ mxf_write_umid(s, 1);
}
static void mxf_write_d10_video_packet(AVFormatContext *s, AVStream *st, AVPacket *pkt)
{
MXFContext *mxf = s->priv_data;
ByteIOContext *pb = s->pb;
- int frame_size = (pkt->size<<3) /
- (st->codec->channels*av_get_bits_per_sample(st->codec->codec_id));
+ int frame_size = pkt->size / st->codec->block_align;
uint8_t *samples = pkt->data;
uint8_t *end = pkt->data + pkt->size;
int i;
for (i = 0; i < st->codec->channels; i++) {
uint32_t sample;
if (st->codec->codec_id == CODEC_ID_PCM_S24LE) {
- sample = (AV_RL24(samples)<< 4)|((samples==pkt->data)<<3) | i;
+ sample = AV_RL24(samples)<< 4;
samples += 3;
} else {
- sample = (AV_RL16(samples)<<12)|((samples==pkt->data)<<3) | i;
+ sample = AV_RL16(samples)<<12;
samples += 2;
}
- put_le32(pb, sample);
+ put_le32(pb, sample | i);
}
for (; i < 8; i++)
- put_le32(pb, 0);
+ put_le32(pb, i);
}
}