示例#1
0
int mxf_fill_to_position(MXFFile *mxfFile, uint64_t position)
{
    int64_t filePos;
    uint64_t fillSize;
    uint8_t llen;

    CHK_ORET((filePos = mxf_file_tell(mxfFile)) >= 0);

    if ((uint64_t)filePos == position)
    {
        return 1;
    }

    CHK_ORET(((uint64_t)filePos <= position - mxf_get_min_llen(mxfFile) + mxfKey_extlen));

    CHK_ORET(mxf_write_k(mxfFile, &g_KLVFill_key));

    fillSize = position - filePos - mxfKey_extlen;
    llen = mxf_get_llen(mxfFile, fillSize);
    assert(fillSize >= llen);
    fillSize -= llen;

    CHK_ORET(mxf_write_l(mxfFile, fillSize));
    CHK_ORET(mxf_write_zeros(mxfFile, fillSize));

    return 1;
}
示例#2
0
int mxf_mark_index_start(MXFFile *mxfFile, MXFPartition *partition)
{
    int64_t filePos;
    CHK_ORET((filePos = mxf_file_tell(mxfFile)) >= 0);

    partition->indexMarkInPos = filePos;
    return 1;
}
示例#3
0
int mxf_allocate_space_to_kag(MXFFile *mxfFile, MXFPartition *partition, uint32_t size)
{
    int64_t filePos;
    uint64_t relativeFilePos;
    int64_t fillSize;
    uint8_t llen;

    assert(partition->kagSize > 0);

    if (size == 0 && partition->kagSize == 1)
    {
        return 1;
    }

    CHK_ORET((filePos = mxf_file_tell(mxfFile)) >= 0);
    CHK_ORET((uint64_t)filePos > partition->thisPartition);
    relativeFilePos = filePos + size - partition->thisPartition;

    if (size != 0 || (relativeFilePos % partition->kagSize) != 0)
    {
        CHK_ORET(mxf_write_k(mxfFile, &g_KLVFill_key));

        fillSize = (int64_t)size - mxfKey_extlen;
        if (partition->kagSize > 1)
        {
            fillSize += partition->kagSize - relativeFilePos % partition->kagSize;
        }

        if (fillSize >= 0)
        {
            llen = mxf_get_llen(mxfFile, fillSize);
        }
        else
        {
            llen = 0;
        }
        while (fillSize - llen < 0)
        {
            fillSize += partition->kagSize;
            if (fillSize >= 0)
            {
                llen = mxf_get_llen(mxfFile, fillSize);
            }
            else
            {
                llen = 0;
            }
        }
        fillSize -= llen;

        CHK_ORET(mxf_write_l(mxfFile, fillSize));
        CHK_ORET(mxf_write_zeros(mxfFile, fillSize));
    }

    return 1;
}
示例#4
0
int mxf_mark_index_end(MXFFile *mxfFile, MXFPartition *partition)
{
    int64_t filePos;

    CHK_ORET(partition->indexMarkInPos >= 0);
    CHK_ORET((filePos = mxf_file_tell(mxfFile)) >= 0);
    CHK_ORET(filePos >= partition->indexMarkInPos);

    partition->indexByteCount = filePos - partition->indexMarkInPos;
    partition->indexMarkInPos = -1;
    return 1;
}
int mxf_finalize_essence_element_write(MXFFile *mxfFile, MXFEssenceElement *essenceElement)
{
    int64_t filePos;

    assert(essenceElement != NULL);

    CHK_ORET((filePos = mxf_file_tell(mxfFile)) >= 0);

    CHK_ORET(mxf_file_seek(mxfFile, essenceElement->startFilePos + 16, SEEK_SET));
    CHK_ORET(mxf_write_fixed_l(mxfFile, essenceElement->llen, essenceElement->totalLen));

    CHK_ORET(mxf_file_seek(mxfFile, filePos, SEEK_SET));

    return 1;
}
int mxf_open_essence_element_read(MXFFile *mxfFile, const mxfKey *key, uint8_t llen, uint64_t len,
                                  MXFEssenceElement **essenceElement)
{
    MXFEssenceElement *newEssenceElement = NULL;
    int64_t filePos;

    CHK_ORET(create_essence_element(key, llen, &newEssenceElement));
    newEssenceElement->totalLen = len;

    CHK_OFAIL((filePos = mxf_file_tell(mxfFile)) >= 0);
    newEssenceElement->startFilePos = filePos;
    newEssenceElement->currentFilePos = newEssenceElement->startFilePos;

    *essenceElement = newEssenceElement;
    return 1;

fail:
    SAFE_FREE(newEssenceElement);
    return 0;
}
示例#7
0
int mxf_write_partition(MXFFile *mxfFile, MXFPartition *partition)
{
    uint32_t essenceContainerLen = (uint32_t)mxf_get_list_length(&partition->essenceContainers);
    uint64_t packLen = 88 + mxfUL_extlen * essenceContainerLen;
    int64_t filePos;
    MXFListIterator iter;

    CHK_ORET((filePos = mxf_file_tell(mxfFile)) >= 0);
    partition->thisPartition = filePos - mxf_get_runin_len(mxfFile);
    if (mxf_is_footer_partition_pack(&partition->key))
    {
        partition->footerPartition = partition->thisPartition;
    }

    CHK_ORET(mxf_write_kl(mxfFile, &partition->key, packLen));

    CHK_ORET(mxf_write_uint16(mxfFile, partition->majorVersion));
    CHK_ORET(mxf_write_uint16(mxfFile, partition->minorVersion));
    CHK_ORET(mxf_write_uint32(mxfFile, partition->kagSize));
    CHK_ORET(mxf_write_uint64(mxfFile, partition->thisPartition));
    CHK_ORET(mxf_write_uint64(mxfFile, partition->previousPartition));
    CHK_ORET(mxf_write_uint64(mxfFile, partition->footerPartition));
    CHK_ORET(mxf_write_uint64(mxfFile, partition->headerByteCount));
    CHK_ORET(mxf_write_uint64(mxfFile, partition->indexByteCount));
    CHK_ORET(mxf_write_uint32(mxfFile, partition->indexSID));
    CHK_ORET(mxf_write_uint64(mxfFile, partition->bodyOffset));
    CHK_ORET(mxf_write_uint32(mxfFile, partition->bodySID));
    CHK_ORET(mxf_write_ul(mxfFile, &partition->operationalPattern));
    CHK_ORET(mxf_write_batch_header(mxfFile, essenceContainerLen, mxfUL_extlen));

    mxf_initialise_list_iter(&iter, &partition->essenceContainers);
    while (mxf_next_list_iter_element(&iter))
    {
        CHK_ORET(mxf_write_ul(mxfFile, (mxfUL*)mxf_get_iter_element(&iter)));
    }

    return 1;
}
示例#8
0
int test_read(const char* filename)
{
    MXFFile* mxfFile = NULL;
    mxfKey key;
    uint8_t llen;
    uint64_t len;
    mxfLocalTag tag;
    uint8_t indata[256];
    uint8_t valueu8;
    uint16_t valueu16;
    uint32_t valueu32;
    uint64_t valueu64;
    int8_t value8;
    int16_t value16;
    int32_t value32;
    int64_t value64;
    mxfUL ul;
    mxfUID uid;
    mxfUUID uuid;
    uint32_t ablen;
    uint32_t abelen;

    if (!mxf_disk_file_open_read(filename, &mxfFile))
    {
        mxf_log_error("Failed to open '%s'" LOG_LOC_FORMAT, filename, LOG_LOC_PARAMS);
        return 0;
    }

    /* TEST */
    CHK_OFAIL(mxf_file_read(mxfFile, indata, 100) == 100);
    CHK_OFAIL(memcmp(data, indata, 100) == 0);
    CHK_OFAIL(mxf_file_getc(mxfFile) == 0xff);
    CHK_OFAIL(mxf_file_getc(mxfFile) == 0xff);
    CHK_OFAIL(mxf_read_uint8(mxfFile, &valueu8));
    CHK_OFAIL(valueu8 == 0x0f);
    CHK_OFAIL(mxf_read_uint16(mxfFile, &valueu16));
    CHK_OFAIL(valueu16 == 0x0f00);
    CHK_OFAIL(mxf_read_uint32(mxfFile, &valueu32));
    CHK_OFAIL(valueu32 == 0x0f000000);
    CHK_OFAIL(mxf_read_uint64(mxfFile, &valueu64));
    CHK_OFAIL(valueu64 == 0x0f00000000000000LL);
    CHK_OFAIL(mxf_read_int8(mxfFile, &value8));
    CHK_OFAIL(value8 == -0x0f);
    CHK_OFAIL(mxf_read_int16(mxfFile, &value16));
    CHK_OFAIL(value16 == -0x0f00);
    CHK_OFAIL(mxf_read_int32(mxfFile, &value32));
    CHK_OFAIL(value32 == -0x0f000000);
    CHK_OFAIL(mxf_read_int64(mxfFile, &value64));
    CHK_OFAIL(value64 == -0x0f00000000000000LL);
    CHK_OFAIL(mxf_read_local_tag(mxfFile, &tag));
    CHK_OFAIL(tag == 0xffaa);
    CHK_OFAIL(mxf_read_k(mxfFile, &key));
    CHK_OFAIL(mxf_equals_key(&key, &someKey));
    CHK_OFAIL(mxf_read_l(mxfFile, &llen, &len));
    CHK_OFAIL(llen == 1 && len == 0x01);
    CHK_OFAIL(mxf_read_l(mxfFile, &llen, &len));
    CHK_OFAIL(llen == 2 && len == 0x80);
    CHK_OFAIL(mxf_read_l(mxfFile, &llen, &len));
    CHK_OFAIL(llen == 3 && len == 0x8000);
    CHK_OFAIL(mxf_read_l(mxfFile, &llen, &len));
    CHK_OFAIL(llen == 4 && len == 0x800000);
    CHK_OFAIL(mxf_read_l(mxfFile, &llen, &len));
    CHK_OFAIL(llen == 5 && len == 0x80000000);
    CHK_OFAIL(mxf_read_l(mxfFile, &llen, &len));
    CHK_OFAIL(llen == 6 && len == 0x8000000000LL);
    CHK_OFAIL(mxf_read_l(mxfFile, &llen, &len));
    CHK_OFAIL(llen == 7 && len == 0x800000000000LL);
    CHK_OFAIL(mxf_read_l(mxfFile, &llen, &len));
    CHK_OFAIL(llen == 8 && len == 0x80000000000000LL);
    CHK_OFAIL(mxf_read_l(mxfFile, &llen, &len));
    CHK_OFAIL(llen == 9 && len == 0x8000000000000000LL);
    CHK_OFAIL(mxf_read_kl(mxfFile, &key, &llen, &len));
    CHK_OFAIL(mxf_equals_key(&key, &someKey));
    CHK_OFAIL(llen == 3 && len == 0xf100);
    CHK_OFAIL(mxf_read_l(mxfFile, &llen, &len));
    CHK_OFAIL(llen == 8 && len == 0x10);
    CHK_OFAIL(mxf_read_l(mxfFile, &llen, &len));
    CHK_OFAIL(llen == 4 && len == 0x10);
    CHK_OFAIL(mxf_read_kl(mxfFile, &key, &llen, &len));
    CHK_OFAIL(mxf_equals_key(&key, &someKey));
    CHK_OFAIL(llen == 8 && len == 0x1000);
    CHK_OFAIL(mxf_read_ul(mxfFile, &ul));
    CHK_OFAIL(mxf_equals_ul(&ul, &someUL));
    CHK_OFAIL(mxf_read_uid(mxfFile, &uid));
    CHK_OFAIL(mxf_equals_uid(&uid, &someUID));
    CHK_OFAIL(mxf_read_uuid(mxfFile, &uuid));
    CHK_OFAIL(mxf_equals_uuid(&uuid, &someUUID));
    CHK_OFAIL(mxf_read_batch_header(mxfFile, &ablen, &abelen));
    CHK_OFAIL(ablen == 2 && abelen == 16);
    CHK_OFAIL(mxf_read_array_header(mxfFile, &ablen, &abelen));
    CHK_OFAIL(ablen == 4 && abelen == 32);


    mxf_file_close(&mxfFile);

    
    /* test reading from a byte buffer */
    
    const uint8_t data[5] = {1, 2, 3, 4, 5};
    
    if (!mxf_byte_array_wrap_read(data, sizeof(data), &mxfFile))
    {
        mxf_log_error("Failed to open byte array as MXF file" LOG_LOC_FORMAT, LOG_LOC_PARAMS);
        return 0;
    }

    CHK_OFAIL(mxf_file_tell(mxfFile) == 0);
    CHK_OFAIL(mxf_file_getc(mxfFile) == 1);
    CHK_OFAIL(mxf_file_tell(mxfFile) == 1);
    CHK_OFAIL(mxf_file_read(mxfFile, indata, 4));
    CHK_OFAIL(indata[0] == 2 && indata[1] == 3 && indata[2] == 4 && indata[3] == 5);
    CHK_OFAIL(mxf_file_tell(mxfFile) == 5);
    CHK_OFAIL(mxf_file_eof(mxfFile));
    CHK_OFAIL(mxf_file_getc(mxfFile) == EOF);
    CHK_OFAIL(mxf_file_seek(mxfFile, 0, SEEK_SET));
    CHK_OFAIL(mxf_file_tell(mxfFile) == 0);
    CHK_OFAIL(mxf_file_getc(mxfFile) == 1);
    CHK_OFAIL(mxf_file_seek(mxfFile, 2, SEEK_CUR));
    CHK_OFAIL(mxf_file_tell(mxfFile) == 3);
    CHK_OFAIL(mxf_file_getc(mxfFile) == 4);
    CHK_OFAIL(mxf_file_seek(mxfFile, 0, SEEK_END));
    CHK_OFAIL(mxf_file_tell(mxfFile) == 4);
    CHK_OFAIL(mxf_file_getc(mxfFile) == 5);
    CHK_OFAIL(!mxf_file_seek(mxfFile, 5, SEEK_END)); /* should fail */
    CHK_OFAIL(mxf_file_tell(mxfFile) == 5);
    
    
    mxf_file_close(&mxfFile);

    
    return 1;
    
fail:
    mxf_file_close(&mxfFile);
    return 0;
}
示例#9
0
int write_dv50(FILE* dv50File, MXFFile* mxfFile, int test)
{
    MXFFilePartitions partitions;
    MXFPartition* headerPartition;
    MXFPartition* bodyPartition;
    MXFPartition* footerPartition;
    MXFHeaderMetadata* headerMetadata = NULL;
    MXFMetadataSet* metaDictSet = NULL;
    MXFMetadataSet* prefaceSet = NULL;
    MXFMetadataSet* identSet = NULL;
    MXFMetadataSet* contentStorageSet = NULL;
    MXFMetadataSet* sourcePackageSet = NULL;
    MXFMetadataSet* materialPackageSet = NULL;
    MXFMetadataSet* sourcePackageTrackSet = NULL;
    MXFMetadataSet* materialPackageTrackSet = NULL;
    MXFMetadataSet* sequenceSet = NULL;
    MXFMetadataSet* sourceClipSet = NULL;
    MXFMetadataSet* essContainerDataSet = NULL;
    MXFMetadataSet* cdciDescriptorSet = NULL;
    MXFDataModel* dataModel = NULL;
    MXFIndexTableSegment* indexSegment = NULL;
    MXFEssenceElement* essenceElement = NULL;
    MXFMetadataItem* durationItem1 = NULL;
    MXFMetadataItem* durationItem2 = NULL;
    MXFMetadataItem* durationItem3 = NULL;
    MXFMetadataItem* durationItem4 = NULL;
    MXFMetadataItem* durationItem5 = NULL;
    MXFMetadataItem* imageSizeItem = NULL;
    mxfTimestamp now;
    uint32_t bodySID = 1;
    uint32_t indexSID = 2;
    mxfUUID thisGeneration;
    mxfUTF16Char* companyName = L"BBC Research";
    mxfUTF16Char* productName = L"Write Avid DV-50 example";
    mxfUTF16Char* versionString = L"Alpha version";
    mxfUMID sourcePackageUMID;
    mxfUMID materialPackageUMID;
    uint32_t sourceTrackID = 1;
    uint32_t sourceTrackNumber = 0x18010201;
    mxfRational sampleRate = {25, 1};
    mxfRational editRate = sampleRate;
    mxfLength duration = 0;
    mxfRational aspectRatio = {4, 3};
    mxfUUID indexSegmentUUID;
    uint32_t frameSize = 288000;
    int32_t imageSize = 0;
    int32_t resolutionID = 0x8e;
    const uint32_t essenceBufferSize = 4096;
    uint8_t buffer[4096];
    int done = 0;
    uint8_t* arrayElement;
    int64_t headerMetadataPos;
    
    
    mxf_generate_uuid(&thisGeneration);
    mxf_get_timestamp_now(&now);
    /* Older Avids could fail when given files with UMIDs generated using
       other methods. (Note: not 100% sure this is true) */
    mxf_generate_aafsdk_umid(&sourcePackageUMID);
    mxf_generate_aafsdk_umid(&materialPackageUMID);
    mxf_generate_uuid(&indexSegmentUUID);
    
    mxf_initialise_file_partitions(&partitions);

    
    /* set the minimum llen */
    mxf_file_set_min_llen(mxfFile, 4);
    
    
    /* load the data model, plus AVID extensions */
    
    CHK_ORET(mxf_load_data_model(&dataModel));
    CHK_ORET(mxf_avid_load_extensions(dataModel));
    CHK_ORET(mxf_finalise_data_model(dataModel));
    
    
    
    /* write the header partition pack */

    CHK_ORET(mxf_append_new_partition(&partitions, &headerPartition));
    headerPartition->key = MXF_PP_K(ClosedComplete, Header);
    headerPartition->majorVersion = 1;
    headerPartition->minorVersion = 2;
    headerPartition->kagSize = 0x100;
    headerPartition->operationalPattern = MXF_OP_L(atom, NTracks_1SourceClip);
    CHK_ORET(mxf_append_partition_esscont_label(headerPartition, &MXF_EC_L(DVBased_50_625_50_ClipWrapped)));
    
    CHK_ORET(mxf_write_partition(mxfFile, headerPartition));
    CHK_ORET(mxf_fill_to_kag(mxfFile, headerPartition));
    

    
    /* create the header metadata */
    
    CHK_ORET(mxf_create_header_metadata(&headerMetadata, dataModel));
    
    
    /* create the Avid meta-dictionary */
    
    CHK_ORET(mxf_avid_create_default_metadictionary(headerMetadata, &metaDictSet));
    
    
    /* Preface */
    CHK_ORET(mxf_create_set(headerMetadata, &MXF_SET_K(Preface), &prefaceSet));
    CHK_ORET(mxf_set_timestamp_item(prefaceSet, &MXF_ITEM_K(Preface, LastModifiedDate), &now));
    CHK_ORET(mxf_set_version_type_item(prefaceSet, &MXF_ITEM_K(Preface, Version), 0x0102));
    CHK_ORET(mxf_set_ul_item(prefaceSet, &MXF_ITEM_K(Preface, OperationalPattern), &MXF_OP_L(atom, NTracks_1SourceClip)));
    CHK_ORET(mxf_alloc_array_item_elements(prefaceSet, &MXF_ITEM_K(Preface, EssenceContainers), mxfUL_extlen, 1, &arrayElement));
    mxf_set_ul(&MXF_EC_L(DVBased_50_625_50_ClipWrapped), arrayElement);

    
    /* Preface - Identification */
    CHK_ORET(mxf_create_set(headerMetadata, &MXF_SET_K(Identification), &identSet));
    CHK_ORET(mxf_add_array_item_strongref(prefaceSet, &MXF_ITEM_K(Preface, Identifications), identSet));
    CHK_ORET(mxf_set_uuid_item(identSet, &MXF_ITEM_K(Identification, ThisGenerationUID), &thisGeneration));
    CHK_ORET(mxf_set_utf16string_item(identSet, &MXF_ITEM_K(Identification, CompanyName), companyName));
    CHK_ORET(mxf_set_utf16string_item(identSet, &MXF_ITEM_K(Identification, ProductName), productName));
    CHK_ORET(mxf_set_utf16string_item(identSet, &MXF_ITEM_K(Identification, VersionString), versionString));
    CHK_ORET(mxf_set_uuid_item(identSet, &MXF_ITEM_K(Identification, ProductUID), &g_WrapDV50ProductUID_uuid));
    CHK_ORET(mxf_set_timestamp_item(identSet, &MXF_ITEM_K(Identification, ModificationDate), &now));
    CHK_ORET(mxf_set_product_version_item(identSet, &MXF_ITEM_K(Identification, ToolkitVersion), mxf_get_version()));
    if (test)
    {
        /* use the same string on all platforms to make checking diffs easier */
        CHK_ORET(mxf_set_utf16string_item(identSet, &MXF_ITEM_K(Identification, Platform), L"test platform string"));
    }
    else
    {
        CHK_ORET(mxf_set_utf16string_item(identSet, &MXF_ITEM_K(Identification, Platform), mxf_get_platform_wstring()));
    }
    
    
    /* Preface - ContentStorage */
    CHK_ORET(mxf_create_set(headerMetadata, &MXF_SET_K(ContentStorage), &contentStorageSet));
    CHK_ORET(mxf_set_strongref_item(prefaceSet, &MXF_ITEM_K(Preface, ContentStorage), contentStorageSet));
    
    
    /* Preface - ContentStorage - MaterialPackage */
    CHK_ORET(mxf_create_set(headerMetadata, &MXF_SET_K(MaterialPackage), &materialPackageSet));
    CHK_ORET(mxf_add_array_item_strongref(contentStorageSet, &MXF_ITEM_K(ContentStorage, Packages), materialPackageSet));
    CHK_ORET(mxf_set_umid_item(materialPackageSet, &MXF_ITEM_K(GenericPackage, PackageUID), &materialPackageUMID));
    CHK_ORET(mxf_set_timestamp_item(materialPackageSet, &MXF_ITEM_K(GenericPackage, PackageCreationDate), &now));
    CHK_ORET(mxf_set_timestamp_item(materialPackageSet, &MXF_ITEM_K(GenericPackage, PackageModifiedDate), &now));
    CHK_ORET(mxf_set_utf16string_item(materialPackageSet, &MXF_ITEM_K(GenericPackage, Name), L"writedv50 material"));

    /* Preface - ContentStorage - MaterialPackage - Timeline Track */    
    CHK_ORET(mxf_create_set(headerMetadata, &MXF_SET_K(Track), &materialPackageTrackSet));
    CHK_ORET(mxf_add_array_item_strongref(materialPackageSet, &MXF_ITEM_K(GenericPackage, Tracks), materialPackageTrackSet));
    CHK_ORET(mxf_set_uint32_item(materialPackageTrackSet, &MXF_ITEM_K(GenericTrack, TrackID), sourceTrackID));
    CHK_ORET(mxf_set_uint32_item(materialPackageTrackSet, &MXF_ITEM_K(GenericTrack, TrackNumber), sourceTrackNumber));
    CHK_ORET(mxf_set_rational_item(materialPackageTrackSet, &MXF_ITEM_K(Track, EditRate), &editRate));
    CHK_ORET(mxf_set_position_item(materialPackageTrackSet, &MXF_ITEM_K(Track, Origin), 0));

    /* Preface - ContentStorage - MaterialPackage - Timeline Track - Sequence */    
    CHK_ORET(mxf_create_set(headerMetadata, &MXF_SET_K(Sequence), &sequenceSet));
    CHK_ORET(mxf_set_strongref_item(materialPackageTrackSet, &MXF_ITEM_K(GenericTrack, Sequence), sequenceSet));
    CHK_ORET(mxf_set_ul_item(sequenceSet, &MXF_ITEM_K(StructuralComponent, DataDefinition), &MXF_DDEF_L(LegacyPicture)));
    CHK_ORET(mxf_set_length_item(sequenceSet, &MXF_ITEM_K(StructuralComponent, Duration), duration));

    CHK_ORET(mxf_get_item(sequenceSet, &MXF_ITEM_K(StructuralComponent, Duration), &durationItem1));

    /* Preface - ContentStorage - MaterialPackage - Timeline Track - Sequence - SourceClip */    
    CHK_ORET(mxf_create_set(headerMetadata, &MXF_SET_K(SourceClip), &sourceClipSet));
    CHK_ORET(mxf_add_array_item_strongref(sequenceSet, &MXF_ITEM_K(Sequence, StructuralComponents), sourceClipSet));
    CHK_ORET(mxf_set_ul_item(sourceClipSet, &MXF_ITEM_K(StructuralComponent, DataDefinition), &MXF_DDEF_L(LegacyPicture)));
    CHK_ORET(mxf_set_length_item(sourceClipSet, &MXF_ITEM_K(StructuralComponent, Duration), duration));
    CHK_ORET(mxf_set_position_item(sourceClipSet, &MXF_ITEM_K(SourceClip, StartPosition), 0));
    CHK_ORET(mxf_set_umid_item(sourceClipSet, &MXF_ITEM_K(SourceClip, SourcePackageID), &sourcePackageUMID));
    CHK_ORET(mxf_set_uint32_item(sourceClipSet, &MXF_ITEM_K(SourceClip, SourceTrackID), sourceTrackID));

    CHK_ORET(mxf_get_item(sourceClipSet, &MXF_ITEM_K(StructuralComponent, Duration), &durationItem2));
    
    
    /* Preface - ContentStorage - SourcePackage */
    CHK_ORET(mxf_create_set(headerMetadata, &MXF_SET_K(SourcePackage), &sourcePackageSet));
    CHK_ORET(mxf_add_array_item_strongref(contentStorageSet, &MXF_ITEM_K(ContentStorage, Packages), sourcePackageSet));
    CHK_ORET(mxf_set_weakref_item(prefaceSet, &MXF_ITEM_K(Preface, PrimaryPackage), sourcePackageSet));
    CHK_ORET(mxf_set_umid_item(sourcePackageSet, &MXF_ITEM_K(GenericPackage, PackageUID), &sourcePackageUMID));
    CHK_ORET(mxf_set_timestamp_item(sourcePackageSet, &MXF_ITEM_K(GenericPackage, PackageCreationDate), &now));
    CHK_ORET(mxf_set_timestamp_item(sourcePackageSet, &MXF_ITEM_K(GenericPackage, PackageModifiedDate), &now));
    CHK_ORET(mxf_set_utf16string_item(sourcePackageSet, &MXF_ITEM_K(GenericPackage, Name), L"writedv50 source"));

    /* Preface - ContentStorage - SourcePackage - Timeline Track */    
    CHK_ORET(mxf_create_set(headerMetadata, &MXF_SET_K(Track), &sourcePackageTrackSet));
    CHK_ORET(mxf_add_array_item_strongref(sourcePackageSet, &MXF_ITEM_K(GenericPackage, Tracks), sourcePackageTrackSet));
    CHK_ORET(mxf_set_uint32_item(sourcePackageTrackSet, &MXF_ITEM_K(GenericTrack, TrackID), sourceTrackID));
    CHK_ORET(mxf_set_uint32_item(sourcePackageTrackSet, &MXF_ITEM_K(GenericTrack, TrackNumber), sourceTrackNumber));
    CHK_ORET(mxf_set_rational_item(sourcePackageTrackSet, &MXF_ITEM_K(Track, EditRate), &editRate));
    CHK_ORET(mxf_set_position_item(sourcePackageTrackSet, &MXF_ITEM_K(Track, Origin), 0));

    /* Preface - ContentStorage - SourcePackage - Timeline Track - Sequence */    
    CHK_ORET(mxf_create_set(headerMetadata, &MXF_SET_K(Sequence), &sequenceSet));
    CHK_ORET(mxf_set_strongref_item(sourcePackageTrackSet, &MXF_ITEM_K(GenericTrack, Sequence), sequenceSet));
    CHK_ORET(mxf_set_ul_item(sequenceSet, &MXF_ITEM_K(StructuralComponent, DataDefinition), &MXF_DDEF_L(LegacyPicture)));
    CHK_ORET(mxf_set_length_item(sequenceSet, &MXF_ITEM_K(StructuralComponent, Duration), duration));

    CHK_ORET(mxf_get_item(sequenceSet, &MXF_ITEM_K(StructuralComponent, Duration), &durationItem3));

    /* Preface - ContentStorage - SourcePackage - Timeline Track - Sequence - SourceClip */    
    CHK_ORET(mxf_create_set(headerMetadata, &MXF_SET_K(SourceClip), &sourceClipSet));
    CHK_ORET(mxf_add_array_item_strongref(sequenceSet, &MXF_ITEM_K(Sequence, StructuralComponents), sourceClipSet));
    CHK_ORET(mxf_set_ul_item(sourceClipSet, &MXF_ITEM_K(StructuralComponent, DataDefinition), &MXF_DDEF_L(LegacyPicture)));
    CHK_ORET(mxf_set_length_item(sourceClipSet, &MXF_ITEM_K(StructuralComponent, Duration), duration));
    CHK_ORET(mxf_set_position_item(sourceClipSet, &MXF_ITEM_K(SourceClip, StartPosition), 0));
    CHK_ORET(mxf_set_umid_item(sourceClipSet, &MXF_ITEM_K(SourceClip, SourcePackageID), &g_Null_UMID));
    CHK_ORET(mxf_set_uint32_item(sourceClipSet, &MXF_ITEM_K(SourceClip, SourceTrackID), 0));

    CHK_ORET(mxf_get_item(sourceClipSet, &MXF_ITEM_K(StructuralComponent, Duration), &durationItem4));
    
    /* Preface - ContentStorage - SourcePackage - CDCIEssenceDescriptor */    
    CHK_ORET(mxf_create_set(headerMetadata, &MXF_SET_K(CDCIEssenceDescriptor), &cdciDescriptorSet));
    CHK_ORET(mxf_set_strongref_item(sourcePackageSet, &MXF_ITEM_K(SourcePackage, Descriptor), cdciDescriptorSet));
    CHK_ORET(mxf_set_rational_item(cdciDescriptorSet, &MXF_ITEM_K(FileDescriptor, SampleRate), &sampleRate));
    CHK_ORET(mxf_set_length_item(cdciDescriptorSet, &MXF_ITEM_K(FileDescriptor, ContainerDuration), duration));
    CHK_ORET(mxf_set_ul_item(cdciDescriptorSet, &MXF_ITEM_K(FileDescriptor, EssenceContainer), &MXF_EC_L(DVBased_50_625_50_ClipWrapped)));
    CHK_ORET(mxf_set_ul_item(cdciDescriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, PictureEssenceCoding), &MXF_CMDEF_L(DVBased_50_625_50)));
    CHK_ORET(mxf_set_uint32_item(cdciDescriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, StoredHeight), 288));
    CHK_ORET(mxf_set_uint32_item(cdciDescriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, StoredWidth), 720));
    CHK_ORET(mxf_set_uint32_item(cdciDescriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, SampledHeight), 288));
    CHK_ORET(mxf_set_uint32_item(cdciDescriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, SampledWidth), 720));
    CHK_ORET(mxf_set_int32_item(cdciDescriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, SampledXOffset), 0));
    CHK_ORET(mxf_set_int32_item(cdciDescriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, SampledYOffset), 0));
    CHK_ORET(mxf_set_uint32_item(cdciDescriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, DisplayHeight), 288));
    CHK_ORET(mxf_set_uint32_item(cdciDescriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, DisplayWidth), 720));
    CHK_ORET(mxf_set_int32_item(cdciDescriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, DisplayXOffset), 0));
    CHK_ORET(mxf_set_int32_item(cdciDescriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, DisplayYOffset), 0));
    CHK_ORET(mxf_set_uint8_item(cdciDescriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, FrameLayout), 1));
    CHK_ORET(mxf_alloc_array_item_elements(cdciDescriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, VideoLineMap), 4, 2, &arrayElement));
    mxf_set_int32(23, arrayElement);
    mxf_set_int32(335, &arrayElement[4]);
    CHK_ORET(mxf_set_rational_item(cdciDescriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, AspectRatio), &aspectRatio));
    CHK_ORET(mxf_set_uint32_item(cdciDescriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, ImageAlignmentOffset), 1));
    CHK_ORET(mxf_set_uint32_item(cdciDescriptorSet, &MXF_ITEM_K(CDCIEssenceDescriptor, ComponentDepth), 8));
    CHK_ORET(mxf_set_uint32_item(cdciDescriptorSet, &MXF_ITEM_K(CDCIEssenceDescriptor, HorizontalSubsampling), 2));
    CHK_ORET(mxf_set_uint32_item(cdciDescriptorSet, &MXF_ITEM_K(CDCIEssenceDescriptor, VerticalSubsampling), 1));
    CHK_ORET(mxf_set_uint8_item(cdciDescriptorSet, &MXF_ITEM_K(CDCIEssenceDescriptor, ColorSiting), 4));
    CHK_ORET(mxf_set_uint32_item(cdciDescriptorSet, &MXF_ITEM_K(CDCIEssenceDescriptor, BlackRefLevel), 16));
    CHK_ORET(mxf_set_uint32_item(cdciDescriptorSet, &MXF_ITEM_K(CDCIEssenceDescriptor, WhiteReflevel), 235));
    CHK_ORET(mxf_set_uint32_item(cdciDescriptorSet, &MXF_ITEM_K(CDCIEssenceDescriptor, ColorRange), 225));

    CHK_ORET(mxf_get_item(cdciDescriptorSet, &MXF_ITEM_K(FileDescriptor, ContainerDuration), &durationItem5));
    
    CHK_ORET(mxf_set_int32_item(cdciDescriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, ResolutionID), resolutionID));
    CHK_ORET(mxf_set_int32_item(cdciDescriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, FrameSampleSize), frameSize));
    CHK_ORET(mxf_set_int32_item(cdciDescriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, ImageSize), 0));

    CHK_ORET(mxf_get_item(cdciDescriptorSet, &MXF_ITEM_K(GenericPictureEssenceDescriptor, ImageSize), &imageSizeItem));
    
    
    /* Preface - ContentStorage - EssenceContainerData */    
    CHK_ORET(mxf_create_set(headerMetadata, &MXF_SET_K(EssenceContainerData), &essContainerDataSet));
    CHK_ORET(mxf_add_array_item_strongref(contentStorageSet, &MXF_ITEM_K(ContentStorage, EssenceContainerData), essContainerDataSet));
    CHK_ORET(mxf_set_umid_item(essContainerDataSet, &MXF_ITEM_K(EssenceContainerData, LinkedPackageUID), &sourcePackageUMID));
    CHK_ORET(mxf_set_uint32_item(essContainerDataSet, &MXF_ITEM_K(EssenceContainerData, IndexSID), indexSID));
    CHK_ORET(mxf_set_uint32_item(essContainerDataSet, &MXF_ITEM_K(EssenceContainerData, BodySID), bodySID));


    /* write the header metadata with Avid extensions */    

    CHK_ORET((headerMetadataPos = mxf_file_tell(mxfFile)) >= 0);
    
    CHK_ORET(mxf_mark_header_start(mxfFile, headerPartition));
    CHK_ORET(mxf_avid_write_header_metadata(mxfFile, headerMetadata, headerPartition));
    CHK_ORET(mxf_fill_to_kag(mxfFile, headerPartition));
    CHK_ORET(mxf_mark_header_end(mxfFile, headerPartition));
    


    /* write the body partition pack */

    CHK_ORET(mxf_append_new_from_partition(&partitions, headerPartition, &bodyPartition));
    bodyPartition->key = MXF_PP_K(ClosedComplete, Body);
    bodyPartition->kagSize = 0x200;
    bodyPartition->bodySID = bodySID;

    CHK_ORET(mxf_write_partition(mxfFile, bodyPartition));
    CHK_ORET(mxf_fill_to_kag(mxfFile, bodyPartition));
    
    
    /* write the DV-50 essence element */
    
    CHK_ORET(mxf_open_essence_element_write(mxfFile, &MXF_EE_K(DVClipWrapped), 8, 0, &essenceElement));
    while (!done)
    {
        size_t numRead = fread(buffer, 1, essenceBufferSize, dv50File);
        if (numRead < essenceBufferSize)
        {
            if (!feof(dv50File))
            {
                fprintf(stderr, "Failed to read bytes from dv50 file\n");
                return 0;
            }
            done = 1;
        }
        
        CHK_ORET(mxf_write_essence_element_data(mxfFile, essenceElement, buffer, (uint32_t)numRead));
    }
    duration = essenceElement->totalLen / frameSize;
    imageSize = (int32_t)essenceElement->totalLen;
    CHK_ORET(mxf_finalize_essence_element_write(mxfFile, essenceElement));
    mxf_close_essence_element(&essenceElement);

    CHK_ORET(mxf_fill_to_kag(mxfFile, bodyPartition));


    
    /* write the footer partition pack */

    CHK_ORET(mxf_append_new_from_partition(&partitions, headerPartition, &footerPartition));
    footerPartition->key = MXF_PP_K(ClosedComplete, Footer);
    footerPartition->kagSize = 0x200;
    footerPartition->indexSID = indexSID;

    CHK_ORET(mxf_write_partition(mxfFile, footerPartition));
    CHK_ORET(mxf_fill_to_kag(mxfFile, footerPartition));

    
    /* write the index table segment */
    
    CHK_ORET(mxf_mark_index_start(mxfFile, footerPartition));
    
    CHK_ORET(mxf_create_index_table_segment(&indexSegment)); 
    indexSegment->instanceUID = indexSegmentUUID;
    indexSegment->indexEditRate = editRate;
    indexSegment->indexStartPosition = 0;
    indexSegment->indexDuration = duration;
    indexSegment->editUnitByteCount = frameSize;
    indexSegment->indexSID = indexSID;
    indexSegment->bodySID = bodySID;
    indexSegment->sliceCount = 0;
    indexSegment->posTableCount = 0;
    indexSegment->deltaEntryArray = NULL;
    indexSegment->indexEntryArray = NULL;
    
    CHK_ORET(mxf_write_index_table_segment(mxfFile, indexSegment));
    CHK_ORET(mxf_fill_to_kag(mxfFile, footerPartition));
    
    CHK_ORET(mxf_mark_index_end(mxfFile, footerPartition));
    

    /* write the random index pack */
    
    CHK_ORET(mxf_write_rip(mxfFile, &partitions));

    
    /* update and re-write the header metadata */
    /* Note: the size will not change so it is safe to re-write */
    
    CHK_ORET(mxf_set_length_item(durationItem1->set, &durationItem1->key, duration));
    CHK_ORET(mxf_set_length_item(durationItem2->set, &durationItem2->key, duration));
    CHK_ORET(mxf_set_length_item(durationItem3->set, &durationItem3->key, duration));
    CHK_ORET(mxf_set_length_item(durationItem4->set, &durationItem4->key, duration));
    CHK_ORET(mxf_set_length_item(durationItem5->set, &durationItem5->key, duration));
    CHK_ORET(mxf_set_int32_item(imageSizeItem->set, &imageSizeItem->key, imageSize));

    CHK_ORET(mxf_file_seek(mxfFile, headerMetadataPos, SEEK_SET));
    CHK_ORET(mxf_mark_header_start(mxfFile, headerPartition));
    CHK_ORET(mxf_avid_write_header_metadata(mxfFile, headerMetadata, headerPartition));
    CHK_ORET(mxf_fill_to_kag(mxfFile, headerPartition));
    CHK_ORET(mxf_mark_header_end(mxfFile, headerPartition));
    

    
    
    /* update the partitions */
    
    CHK_ORET(mxf_update_partitions(mxfFile, &partitions));
    
    
       
    /* free memory resources */

    mxf_free_index_table_segment(&indexSegment);
    mxf_clear_file_partitions(&partitions);
    mxf_free_header_metadata(&headerMetadata);
    mxf_free_data_model(&dataModel);
    
    return 1;
}
示例#10
0
int mxf_find_footer_partition(MXFFile *mxfFile)
{
    const uint32_t maxIterations = 250; /* i.e. search maximum 8MB */
    const uint32_t bufferSize = 32768 + 15;
    unsigned char *buffer;
    uint32_t numRead = 0;
    int64_t offset;
    int lastIteration = 0;
    uint32_t i, j;

    CHK_MALLOC_ARRAY_ORET(buffer, unsigned char, bufferSize);

    if (!mxf_file_seek(mxfFile, 0, SEEK_END))
        goto fail;

    offset = mxf_file_tell(mxfFile);

    for (i = 0; i < maxIterations; i++) {
        if (offset < 17) /* file must start with a header partition pack */
            break;
        numRead = bufferSize - 15;
        if (numRead > offset)
            numRead = (uint32_t)offset;

        /* first 15 bytes from last read are used for comparison in this read */
        if (i > 0)
            memcpy(buffer + numRead, buffer, 15);

        if (!mxf_file_seek(mxfFile, offset - numRead, SEEK_SET) ||
            mxf_file_read(mxfFile, buffer, numRead) != numRead)
        {
            break;
        }

        for (j = 0; j < numRead; j++) {
            if (buffer[j]     == g_PartitionPackPrefix_key.octet0 &&
                buffer[j + 1] == g_PartitionPackPrefix_key.octet1 &&
                memcmp(&buffer[j + 2], &g_PartitionPackPrefix_key.octet2, 11) == 0)
            {
                if (buffer[j + 13] == 0x04) {
                    /* found footer partition pack key - seek to it */
                    if (!mxf_file_seek(mxfFile, offset - numRead + j, SEEK_SET))
                        goto fail;

                    SAFE_FREE(buffer);
                    return 1;
                } else if (buffer[j + 13] == 0x02 || buffer[j + 13] == 0x03) {
                    /* found a header or body partition pack key - continue search in this buffer only */
                    lastIteration = 1;
                }
            }
        }
        if (lastIteration)
            break;

        offset -= numRead;
    }

fail:
    SAFE_FREE(buffer);
    return 0;
}
示例#11
0
int main()
{
    MXFPageFile *mxfPageFile;
    MXFFile *mxfFile;
    uint8_t *data;
    int i;

    data = malloc(DATA_SIZE);


    remove_test_files();


    CHECK(mxf_page_file_open_new(g_testFile, PAGE_SIZE, &mxfPageFile));
    mxfFile = mxf_page_file_get_file(mxfPageFile);

    memset(data, 0, DATA_SIZE);

    CHECK(mxf_file_write(mxfFile, data, DATA_SIZE) == DATA_SIZE);

    mxf_file_close(&mxfFile);



    CHECK(mxf_page_file_open_modify(g_testFile, PAGE_SIZE, &mxfPageFile));
    mxfFile = mxf_page_file_get_file(mxfPageFile);

    memset(data, 1, DATA_SIZE);

    CHECK(mxf_file_size(mxfFile) == DATA_SIZE);
    CHECK(mxf_file_read(mxfFile, data, DATA_SIZE) == DATA_SIZE);
    CHECK(mxf_file_eof(mxfFile));
    CHECK(mxf_file_tell(mxfFile) == DATA_SIZE);

    CHECK(mxf_file_write(mxfFile, data, DATA_SIZE) == DATA_SIZE);
    CHECK(mxf_file_eof(mxfFile));
    CHECK(mxf_file_tell(mxfFile) == DATA_SIZE * 2);

    CHECK(mxf_file_seek(mxfFile, 0, SEEK_SET));
    CHECK(mxf_file_tell(mxfFile) == 0);
    CHECK(mxf_file_write(mxfFile, data, DATA_SIZE) == DATA_SIZE);

    mxf_file_close(&mxfFile);



    CHECK(mxf_page_file_open_read(g_testFile, &mxfPageFile));
    mxfFile = mxf_page_file_get_file(mxfPageFile);

    memset(data, 1, DATA_SIZE);

    CHECK(mxf_file_size(mxfFile) == DATA_SIZE * 2);
    CHECK(mxf_file_read(mxfFile, data, DATA_SIZE) == DATA_SIZE);
    CHECK(mxf_file_tell(mxfFile) == DATA_SIZE);
    CHECK(mxf_file_read(mxfFile, data, DATA_SIZE) == DATA_SIZE);
    CHECK(mxf_file_eof(mxfFile));
    CHECK(mxf_file_tell(mxfFile) == DATA_SIZE * 2);
    CHECK(mxf_file_seek(mxfFile, 0, SEEK_SET));
    CHECK(mxf_file_tell(mxfFile) == 0);
    CHECK(mxf_file_read(mxfFile, data, DATA_SIZE) == DATA_SIZE);
    CHECK(mxf_file_tell(mxfFile) == DATA_SIZE);
    CHECK(mxf_file_seek(mxfFile, DATA_SIZE + 1, SEEK_SET));
    CHECK(mxf_file_read(mxfFile, data, DATA_SIZE - 1) == DATA_SIZE - 1);
    CHECK(mxf_file_tell(mxfFile) == DATA_SIZE * 2);
    CHECK(mxf_file_seek(mxfFile, DATA_SIZE - 1, SEEK_SET));
    CHECK(mxf_file_tell(mxfFile) == DATA_SIZE - 1);
    CHECK(mxf_file_seek(mxfFile, DATA_SIZE * 2, SEEK_SET));
    CHECK(mxf_file_tell(mxfFile) == DATA_SIZE * 2);
    CHECK(mxf_file_seek(mxfFile, 0, SEEK_END));
    CHECK(mxf_file_tell(mxfFile) == DATA_SIZE * 2);
    CHECK(mxf_file_seek(mxfFile, -DATA_SIZE * 2, SEEK_END));
    CHECK(mxf_file_tell(mxfFile) == 0);
    CHECK(mxf_file_seek(mxfFile, DATA_SIZE - 5, SEEK_CUR));
    CHECK(mxf_file_tell(mxfFile) == DATA_SIZE - 5);
    CHECK(mxf_file_read(mxfFile, data, DATA_SIZE) == DATA_SIZE);

    mxf_file_close(&mxfFile);



    CHECK(mxf_page_file_open_new("pagetest_out__%d.mxf", PAGE_SIZE, &mxfPageFile));
    mxfFile = mxf_page_file_get_file(mxfPageFile);

    CHECK(mxf_file_write(mxfFile, data, DATA_SIZE) == DATA_SIZE);

    mxf_file_close(&mxfFile);

    CHECK(mxf_page_file_remove("pagetest_out__%d.mxf"));


    /* test forward truncate */

    CHECK(mxf_page_file_open_new(g_testFile, PAGE_SIZE, &mxfPageFile));
    mxfFile = mxf_page_file_get_file(mxfPageFile);

    memset(data, 0, DATA_SIZE);

    for (i = 0; i < 10; i++)
    {
        CHECK(mxf_file_write(mxfFile, data, DATA_SIZE) == DATA_SIZE);
    }

    mxf_file_close(&mxfFile);


    CHECK(mxf_page_file_open_modify(g_testFile, PAGE_SIZE, &mxfPageFile));
    mxfFile = mxf_page_file_get_file(mxfPageFile);

    memset(data, 1, DATA_SIZE);

    CHECK(mxf_page_file_forward_truncate(mxfPageFile));

    for (i = 0; i < 5; i++)
    {
        CHECK(mxf_file_read(mxfFile, data, DATA_SIZE) == DATA_SIZE);
    }
    CHECK(mxf_page_file_forward_truncate(mxfPageFile));

    for (i = 0; i < 4; i++)
    {
        CHECK(mxf_file_read(mxfFile, data, DATA_SIZE) == DATA_SIZE);
    }
    CHECK(mxf_page_file_forward_truncate(mxfPageFile));

    CHECK(mxf_file_read(mxfFile, data, DATA_SIZE) == DATA_SIZE);
    CHECK(mxf_page_file_forward_truncate(mxfPageFile));

    mxf_file_close(&mxfFile);

    CHECK(mxf_page_file_remove(g_testFile));


    free(data);

    return 0;
}