コード例 #1
0
int test_read(const char *filename)
{
    MXFFile *mxfFile = NULL;
    MXFFilePartitions partitions;
    MXFPartition *headerPartition = NULL;
    MXFPartition *bodyPartition1 = NULL;
    MXFPartition *bodyPartition2 = NULL;
    MXFPartition *footerPartition = NULL;
    MXFListIterator iter;
    mxfKey key;
    uint8_t llen;
    uint64_t len;
    int i;
    MXFRIP rip;

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

    mxf_initialise_file_partitions(&partitions);


    /* TEST */

    /* read RIP */
    CHK_OFAIL(mxf_read_rip(mxfFile, &rip));
    CHK_OFAIL(mxf_get_list_length(&rip.entries) == 4);
    CHK_OFAIL(mxf_file_seek(mxfFile, 0, SEEK_SET));
    mxf_initialise_list_iter(&iter, &rip.entries);
    i = 0;
    while (mxf_next_list_iter_element(&iter))
    {
        MXFRIPEntry *entry = (MXFRIPEntry*)mxf_get_iter_element(&iter);
        if (i == 0)
        {
            CHK_OFAIL(entry->bodySID == 0);
            CHK_OFAIL(entry->thisPartition == RUNIN_LEN);
        }
        else if (i == 1)
        {
            CHK_OFAIL(entry->bodySID == 2);
            CHK_OFAIL(entry->thisPartition == RUNIN_LEN + 1161);
        }
        else if (i == 2)
        {
            CHK_OFAIL(entry->bodySID == 3);
            CHK_OFAIL(entry->thisPartition == RUNIN_LEN + 1298);
        }
        else
        {
            CHK_OFAIL(entry->bodySID == 0);
            CHK_OFAIL(entry->thisPartition == RUNIN_LEN + 1554);
        }
        i++;
    }

    /* read header pp, allowing for runin */
    CHK_OFAIL(mxf_read_header_pp_kl_with_runin(mxfFile, &key, &llen, &len));
    CHK_OFAIL(mxf_read_partition(mxfFile, &key, &headerPartition));
    CHK_OFAIL(mxf_append_partition(&partitions, headerPartition));
    CHK_OFAIL(headerPartition->indexSID == 1);
    CHK_OFAIL(headerPartition->bodySID == 0);
    CHK_OFAIL(mxf_get_list_length(&headerPartition->essenceContainers) == 2);
    mxf_initialise_list_iter(&iter, &headerPartition->essenceContainers);
    i = 0;
    while (mxf_next_list_iter_element(&iter))
    {
        mxfUL *label = (mxfUL*)mxf_get_iter_element(&iter);
        if (i == 0)
        {
            CHK_OFAIL(mxf_equals_ul(label, &MXF_EC_L(SD_Unc_625_50i_422_135_FrameWrapped)));
        }
        else
        {
            CHK_OFAIL(mxf_equals_ul(label, &MXF_EC_L(BWFFrameWrapped)));
        }
        i++;
    }

    /* skip filler and read body pp 1 */
    CHK_OFAIL(mxf_read_next_nonfiller_kl(mxfFile, &key, &llen, &len));
    CHK_OFAIL(mxf_is_partition_pack(&key));
    CHK_OFAIL(mxf_read_partition(mxfFile, &key, &bodyPartition1));
    CHK_OFAIL(bodyPartition1->indexSID == 0);
    CHK_OFAIL(bodyPartition1->bodySID == 2);
    CHK_OFAIL(mxf_append_partition(&partitions, bodyPartition1));

    /* skip filler and read body pp 2 */
    CHK_OFAIL(mxf_read_next_nonfiller_kl(mxfFile, &key, &llen, &len));
    CHK_OFAIL(mxf_is_partition_pack(&key));
    CHK_OFAIL(mxf_read_partition(mxfFile, &key, &bodyPartition2));
    CHK_OFAIL(bodyPartition2->indexSID == 0);
    CHK_OFAIL(bodyPartition2->bodySID == 3);
    CHK_OFAIL(mxf_append_partition(&partitions, bodyPartition2));

    /* skip filler and read footer pp */
    CHK_OFAIL(mxf_read_next_nonfiller_kl(mxfFile, &key, &llen, &len));
    CHK_OFAIL(mxf_is_partition_pack(&key));
    CHK_OFAIL(mxf_read_partition(mxfFile, &key, &footerPartition));
    CHK_OFAIL(footerPartition->bodySID == 0);
    CHK_OFAIL(footerPartition->indexSID == 1);
    CHK_OFAIL(mxf_append_partition(&partitions, footerPartition));
    mxf_initialise_list_iter(&iter, &footerPartition->essenceContainers);
    i = 0;
    while (mxf_next_list_iter_element(&iter))
    {
        mxfUL *label = (mxfUL*)mxf_get_iter_element(&iter);
        if (i == 0)
        {
            CHK_OFAIL(mxf_equals_ul(label, &MXF_EC_L(SD_Unc_625_50i_422_135_FrameWrapped)));
        }
        else
        {
            CHK_OFAIL(mxf_equals_ul(label, &MXF_EC_L(BWFFrameWrapped)));
        }
        i++;
    }



    mxf_clear_rip(&rip);
    mxf_file_close(&mxfFile);
    mxf_clear_file_partitions(&partitions);
    return 1;

fail:
    mxf_clear_rip(&rip);
    mxf_file_close(&mxfFile);
    mxf_clear_file_partitions(&partitions);
    return 0;
}
コード例 #2
0
ファイル: archive_mxf_info_lib.c プロジェクト: DraFFty/libMXF
int archive_mxf_read_footer_metadata(const char* filename, MXFDataModel* dataModel, MXFHeaderMetadata** headerMetadata)
{
    MXFPageFile* mxfPageFile = NULL;
    MXFFile* mxfFile = NULL;
    MXFRIP rip;
    MXFRIPEntry* lastRIPEntry = NULL;
    mxfKey key;
    uint8_t llen;
    uint64_t len;
    MXFPartition* footerPartition = NULL;
    int result = 0;
    MXFHeaderMetadata* newHeaderMetadata = NULL;
    
    memset(&rip, 0, sizeof(rip));
 
    
    /* open MXF file */    
    if (strstr(filename, "%d") != NULL)
    {
        CHK_OFAIL_NOMSG(mxf_page_file_open_read(filename, &mxfPageFile));
        mxfFile = mxf_page_file_get_file(mxfPageFile);
    }
    else
    {
        CHK_OFAIL_NOMSG(mxf_disk_file_open_read(filename, &mxfFile));
    }
    
    /* read the RIP */
    CHK_OFAIL_NOMSG(mxf_read_rip(mxfFile, &rip));
    
    /* read footer partition pack */
    CHK_OFAIL_NOMSG((lastRIPEntry = (MXFRIPEntry*)mxf_get_last_list_element(&rip.entries)) != NULL);
    CHK_OFAIL_NOMSG(mxf_file_seek(mxfFile, mxf_get_runin_len(mxfFile) + lastRIPEntry->thisPartition, SEEK_SET));
    CHK_OFAIL_NOMSG(mxf_read_kl(mxfFile, &key, &llen, &len));
    CHK_OFAIL_NOMSG(mxf_is_partition_pack(&key));
    result = 2; /* the file is complete and the presence, or not, of the header metadata will not change */
    *headerMetadata = NULL;
    
    CHK_OFAIL_NOMSG(mxf_is_footer_partition_pack(&key));
    CHK_OFAIL_NOMSG(mxf_read_partition(mxfFile, &key, &footerPartition));
    
    /* read the header metadata */
    CHK_OFAIL_NOMSG(mxf_read_next_nonfiller_kl(mxfFile, &key, &llen, &len));
    CHK_OFAIL_NOMSG(mxf_is_header_metadata(&key));
    CHK_OFAIL_NOMSG(mxf_create_header_metadata(&newHeaderMetadata, dataModel));
    CHK_OFAIL_NOMSG(mxf_read_header_metadata(mxfFile, newHeaderMetadata, 
        footerPartition->headerByteCount, &key, llen, len));

    mxf_free_partition(&footerPartition);
    mxf_clear_rip(&rip);
    mxf_file_close(&mxfFile);
    
    *headerMetadata = newHeaderMetadata;
    newHeaderMetadata = NULL;
    return 1;
 
    
fail:
    mxf_free_header_metadata(&newHeaderMetadata);
    mxf_free_partition(&footerPartition);
    mxf_clear_rip(&rip);
    mxf_file_close(&mxfFile);
    return result;
}
コード例 #3
0
int test_read(const char *filename)
{
    MXFFile *mxfFile = NULL;
    MXFFilePartitions partitions;
    MXFPartition *headerPartition = NULL;
    mxfKey key;
    uint8_t llen;
    uint64_t len;
    int i;
    int k;
    MXFIndexTableSegment *indexSegment = NULL;
    MXFDeltaEntry *deltaEntry;
    MXFIndexEntry *indexEntry;


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

    mxf_initialise_file_partitions(&partitions);

    /* read header pp */
    CHK_OFAIL(mxf_read_header_pp_kl(mxfFile, &key, &llen, &len));
    CHK_OFAIL(mxf_read_partition(mxfFile, &key, len, &headerPartition));
    CHK_OFAIL(mxf_append_partition(&partitions, headerPartition));


    /* TEST */

    /* read index table segment */

    CHK_OFAIL(mxf_read_next_nonfiller_kl(mxfFile, &key, &llen, &len));
    CHK_OFAIL(mxf_is_index_table_segment(&key));
    CHK_OFAIL(mxf_read_index_table_segment(mxfFile, len, &indexSegment));
    CHK_OFAIL(indexSegment->indexEditRate.numerator == 25 && indexSegment->indexEditRate.denominator == 1);
    CHK_OFAIL(indexSegment->indexStartPosition == 0);
    CHK_OFAIL(indexSegment->indexDuration == 0x64);
    CHK_OFAIL(indexSegment->editUnitByteCount == 0x100);
    CHK_OFAIL(indexSegment->indexSID == 1);
    CHK_OFAIL(indexSegment->bodySID == 2);
    CHK_OFAIL(indexSegment->sliceCount == 0);
    CHK_OFAIL(indexSegment->posTableCount == 0);
    CHK_OFAIL(indexSegment->extStartOffset == 0);
    CHK_OFAIL(indexSegment->vbeByteCount == 0);
    CHK_OFAIL(indexSegment->singleIndexLocation == MXF_OPT_BOOL_NOT_PRESENT);
    CHK_OFAIL(indexSegment->singleEssenceLocation == MXF_OPT_BOOL_NOT_PRESENT);
    CHK_OFAIL(indexSegment->forwardIndexDirection == MXF_OPT_BOOL_NOT_PRESENT);
    CHK_OFAIL(indexSegment->deltaEntryArray != 0);
    CHK_OFAIL(indexSegment->indexEntryArray == 0);
    deltaEntry = indexSegment->deltaEntryArray;
    for (i = 0; i < 4; i++)
    {
        CHK_OFAIL(deltaEntry != 0);

        CHK_OFAIL(deltaEntry->posTableIndex == i);
        CHK_OFAIL(deltaEntry->slice == i);
        CHK_OFAIL((int)deltaEntry->elementData == i);

        deltaEntry = deltaEntry->next;
    }

    mxf_free_index_table_segment(&indexSegment);

    /* read index table segment */

    CHK_OFAIL(mxf_read_next_nonfiller_kl(mxfFile, &key, &llen, &len));
    CHK_OFAIL(mxf_is_index_table_segment(&key));
    CHK_OFAIL(mxf_read_index_table_segment(mxfFile, len, &indexSegment));
    CHK_OFAIL(indexSegment->indexEditRate.numerator == 25 && indexSegment->indexEditRate.denominator == 1);
    CHK_OFAIL(indexSegment->indexStartPosition == 0);
    CHK_OFAIL(indexSegment->indexDuration == 0x0a);
    CHK_OFAIL(indexSegment->editUnitByteCount == 0);
    CHK_OFAIL(indexSegment->indexSID == 1);
    CHK_OFAIL(indexSegment->bodySID == 2);
    CHK_OFAIL(indexSegment->sliceCount == 2);
    CHK_OFAIL(indexSegment->posTableCount == 2);
    CHK_OFAIL(indexSegment->extStartOffset == 0);
    CHK_OFAIL(indexSegment->vbeByteCount == 1);
    CHK_OFAIL(indexSegment->singleIndexLocation == MXF_OPT_BOOL_NOT_PRESENT);
    CHK_OFAIL(indexSegment->singleEssenceLocation == MXF_OPT_BOOL_TRUE);
    CHK_OFAIL(indexSegment->forwardIndexDirection == MXF_OPT_BOOL_FALSE);
    CHK_OFAIL(indexSegment->deltaEntryArray == 0);
    CHK_OFAIL(indexSegment->indexEntryArray != 0);
    indexEntry = indexSegment->indexEntryArray;
    for (i = 0; i < indexSegment->indexDuration; i++)
    {
        CHK_OFAIL(indexEntry != 0);

        CHK_OFAIL(indexEntry->temporalOffset == i);
        CHK_OFAIL(indexEntry->keyFrameOffset == i);
        CHK_OFAIL(indexEntry->flags == i);
        CHK_OFAIL((int)indexEntry->streamOffset == i);

        for (k = 0; k < indexSegment->sliceCount; k++)
        {
            CHK_OFAIL((int)indexEntry->sliceOffset[k] == i);
        }

        for (k = 0; k < indexSegment->posTableCount; k++)
        {
            CHK_OFAIL(indexEntry->posTable[k].numerator == i);
            CHK_OFAIL(indexEntry->posTable[k].denominator == i + 1);
        }
        indexEntry = indexEntry->next;
    }



    mxf_free_index_table_segment(&indexSegment);
    mxf_file_close(&mxfFile);
    mxf_clear_file_partitions(&partitions);
    return 1;

fail:
    mxf_free_index_table_segment(&indexSegment);
    mxf_file_close(&mxfFile);
    mxf_clear_file_partitions(&partitions);
    return 0;
}
コード例 #4
0
int test_read(const char *filename)
{
    MXFFile *mxfFile = NULL;
    MXFFilePartitions partitions;
    MXFPartition *headerPartition = NULL;
    MXFPartition *bodyPartition1 = NULL;
    MXFPartition *bodyPartition2 = NULL;
    MXFPartition *footerPartition = NULL;
    mxfKey key;
    uint8_t llen;
    uint64_t len;
    uint8_t essenceData[1024];
    MXFEssenceElement *essenceElement = NULL;
    uint32_t numRead;

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

    mxf_initialise_file_partitions(&partitions);


    /* TEST */

    /* read header pp */
    CHK_OFAIL(mxf_read_header_pp_kl(mxfFile, &key, &llen, &len));
    CHK_OFAIL(mxf_read_partition(mxfFile, &key, &headerPartition));
    CHK_OFAIL(mxf_append_partition(&partitions, headerPartition));

    /* read essence data directly */
    CHK_OFAIL(mxf_read_next_nonfiller_kl(mxfFile, &key, &llen, &len));
    CHK_OFAIL(mxf_is_gc_essence_element(&key));
    CHK_OFAIL(llen == 4 && len == 256);
    CHK_OFAIL(mxf_file_read(mxfFile, essenceData, (uint32_t)len));

    /* read body pp 1 */
    CHK_OFAIL(mxf_read_next_nonfiller_kl(mxfFile, &key, &llen, &len));
    CHK_OFAIL(mxf_is_partition_pack(&key));
    CHK_OFAIL(mxf_read_partition(mxfFile, &key, &bodyPartition1));
    CHK_OFAIL(mxf_append_partition(&partitions, bodyPartition1));

    /* read essence data using MXFEssenceElement */
    CHK_OFAIL(mxf_read_next_nonfiller_kl(mxfFile, &key, &llen, &len));
    CHK_OFAIL(mxf_open_essence_element_read(mxfFile, &key, llen, len, &essenceElement));
    CHK_OFAIL(llen == 8 && len == 1024);
    CHK_OFAIL(mxf_read_essence_element_data(mxfFile, essenceElement, (uint32_t)len, essenceData, &numRead));
    CHK_OFAIL(numRead == len);
    mxf_close_essence_element(&essenceElement);


    /* read body pp 2 */
    CHK_OFAIL(mxf_read_next_nonfiller_kl(mxfFile, &key, &llen, &len));
    CHK_OFAIL(mxf_is_partition_pack(&key));
    CHK_OFAIL(mxf_read_partition(mxfFile, &key, &bodyPartition2));
    CHK_OFAIL(mxf_append_partition(&partitions, bodyPartition2));

    /* read essence data using MXFEssenceElement */
    CHK_OFAIL(mxf_read_next_nonfiller_kl(mxfFile, &key, &llen, &len));
    CHK_OFAIL(mxf_open_essence_element_read(mxfFile, &key, llen, len, &essenceElement));
    CHK_OFAIL(llen == 8 && len == 1024);
    CHK_OFAIL(mxf_read_essence_element_data(mxfFile, essenceElement, 256, essenceData, &numRead));
    CHK_OFAIL(numRead == 256);
    CHK_OFAIL(mxf_read_essence_element_data(mxfFile, essenceElement, 768, &essenceData[256], &numRead));
    CHK_OFAIL(numRead == 768);
    mxf_close_essence_element(&essenceElement);


    /* read footer pp */
    CHK_OFAIL(mxf_read_next_nonfiller_kl(mxfFile, &key, &llen, &len));
    CHK_OFAIL(mxf_is_partition_pack(&key));
    CHK_OFAIL(mxf_read_partition(mxfFile, &key, &footerPartition));
    CHK_OFAIL(mxf_append_partition(&partitions, footerPartition));



    mxf_file_close(&mxfFile);
    mxf_clear_file_partitions(&partitions);
    mxf_close_essence_element(&essenceElement);
    return 1;

fail:
    mxf_file_close(&mxfFile);
    mxf_clear_file_partitions(&partitions);
    mxf_close_essence_element(&essenceElement);
    return 0;
}
コード例 #5
0
static int process_metadata(MXFReader *reader, MXFPartition *partition)
{
    MXFFile *mxfFile = reader->mxfFile;
    EssenceReader *essenceReader = reader->essenceReader;
    EssenceReaderData *data = essenceReader->data;
    mxfKey key;
    uint8_t llen;
    uint64_t len;
    MXFMetadataSet *essContainerDataSet;
    MXFMetadataSet *sourcePackageSet;
    MXFMetadataSet *sourcePackageTrackSet;
    MXFMetadataSet *materialPackageSet;
    MXFMetadataSet *materialPackageTrackSet;
    MXFMetadataSet *descriptorSet;
    MXFArrayItemIterator arrayIter;
    mxfUL dataDefUL;
    MXFTrack *track;
    EssenceTrack *essenceTrack;
    MXFList wrappedTracks;
    MXFList sortedWrappedTracks;
    WrappedTrack *newWrappedTrack = NULL;
    WrappedTrack *wrappedTrack;
    WrappedTrack *sortedWrappedTrack;
    WrappedTrack *prevSortedWrappedTrack;
    WrappedTrack *firstSortedWrappedTrack;
    MXFListIterator listIter;
    MXFListIterator sortedListIter;
    int wasInserted;
    int haveZeroTrackNumber;
    uint32_t trackID;


    mxf_initialise_list(&wrappedTracks, free);
    mxf_initialise_list(&sortedWrappedTracks, NULL);


    /* create and read the header metadata */

    CHK_OFAIL(mxf_read_next_nonfiller_kl(mxfFile, &key, &llen, &len));
    CHK_OFAIL(mxf_is_header_metadata(&key));
    CHK_OFAIL(mxf_create_header_metadata(&data->headerMetadata, reader->dataModel));
    CHK_OFAIL(mxf_read_header_metadata(mxfFile, data->headerMetadata,
        partition->headerByteCount, &key, llen, len));


    /* check for metadata only files */

    if (!mxf_find_singular_set_by_key(data->headerMetadata, &MXF_SET_K(EssenceContainerData), &essContainerDataSet))
    {
        reader->isMetadataOnly = 1;
        return 1;
    }


    /* get the body and index SID from the (single essence container; external essence not supported) */

    CHK_OFAIL(mxf_get_uint32_item(essContainerDataSet, &MXF_ITEM_K(EssenceContainerData, BodySID), &data->bodySID));
    if (mxf_have_item(essContainerDataSet, &MXF_ITEM_K(EssenceContainerData, IndexSID)))
    {
        CHK_OFAIL(mxf_get_uint32_item(essContainerDataSet, &MXF_ITEM_K(EssenceContainerData, IndexSID), &data->indexSID));
    }
    else
    {
        data->indexSID = 0;
    }


    /* get the clip duration */

    CHK_OFAIL(get_clip_duration(data->headerMetadata, &reader->clip, 0));


    /* get the tracks from the (single) material package */

    haveZeroTrackNumber = 0;
    CHK_OFAIL(mxf_find_singular_set_by_key(data->headerMetadata, &MXF_SET_K(MaterialPackage), &materialPackageSet));
    CHK_OFAIL(mxf_uu_get_package_tracks(materialPackageSet, &arrayIter));
    while (mxf_uu_next_track(data->headerMetadata, &arrayIter, &materialPackageTrackSet))
    {
        /* CHK_OFAIL(mxf_uu_get_track_datadef(materialPackageTrackSet, &dataDefUL)); */
        /* NOTE: not failing because files from Omneon were found to have a missing DataDefinition item
           in the Sequence and DMSourceClip referenced by a static DM Track */
        if (!mxf_uu_get_track_datadef(materialPackageTrackSet, &dataDefUL))
        {
            continue;
        }

        if (mxf_is_picture(&dataDefUL) || mxf_is_sound(&dataDefUL))
        {
            CHK_MALLOC_OFAIL(newWrappedTrack, WrappedTrack);
            memset(newWrappedTrack, 0, sizeof(WrappedTrack));
            CHK_OFAIL(mxf_append_list_element(&wrappedTracks, newWrappedTrack));
            wrappedTrack = newWrappedTrack;
            newWrappedTrack = NULL;  /* assigned to list so set to NULL so not free'ed in fail */

            CHK_OFAIL(add_track(reader, &track));
            wrappedTrack->track = track;

            if (mxf_have_item(materialPackageTrackSet, &MXF_ITEM_K(GenericTrack, TrackNumber)))
            {
                CHK_OFAIL(mxf_get_uint32_item(materialPackageTrackSet, &MXF_ITEM_K(GenericTrack, TrackNumber), &wrappedTrack->trackNumber));
            }
            else
            {
                wrappedTrack->trackNumber = 0;
            }
            CHK_OFAIL(mxf_get_uint32_item(materialPackageTrackSet, &MXF_ITEM_K(GenericTrack, TrackID), &wrappedTrack->trackID));
            CHK_OFAIL(mxf_get_rational_item(materialPackageTrackSet, &MXF_ITEM_K(Track, EditRate), &wrappedTrack->editRate));
            CHK_OFAIL(mxf_uu_get_track_duration(materialPackageTrackSet, &wrappedTrack->duration));
            CHK_OFAIL(mxf_uu_get_track_reference(materialPackageTrackSet, &wrappedTrack->sourcePackageUID, &wrappedTrack->sourceTrackID));
            wrappedTrack->isVideo = mxf_is_picture(&dataDefUL);
            track->isVideo = wrappedTrack->isVideo;
            track->materialTrackID = wrappedTrack->trackID;
            track->materialTrackNumber = wrappedTrack->trackNumber;

            if (wrappedTrack->isVideo)
            {
                track->video.frameRate = wrappedTrack->editRate;
            }

            if (wrappedTrack->trackNumber == 0)
            {
                haveZeroTrackNumber = 1;
            }
        }
    }


    /* sort the tracks; use trackNumber if != 0 else use the trackID; video track is always first */

    mxf_initialise_list_iter(&listIter, &wrappedTracks);
    while (mxf_next_list_iter_element(&listIter))
    {
        wrappedTrack = (WrappedTrack*)mxf_get_iter_element(&listIter);

        wasInserted = 0;
        mxf_initialise_list_iter(&sortedListIter, &sortedWrappedTracks);
        while (mxf_next_list_iter_element(&sortedListIter))
        {
            sortedWrappedTrack = (WrappedTrack*)mxf_get_iter_element(&sortedListIter);
            if ((wrappedTrack->track->isVideo && !sortedWrappedTrack->track->isVideo) ||
                (wrappedTrack->track->isVideo == sortedWrappedTrack->track->isVideo &&
                    ((!haveZeroTrackNumber && wrappedTrack->trackNumber < sortedWrappedTrack->trackNumber) ||
                        (haveZeroTrackNumber && wrappedTrack->trackID < sortedWrappedTrack->trackID))))
            {
                CHK_OFAIL(mxf_insert_list_element(&sortedWrappedTracks, mxf_get_list_iter_index(&sortedListIter),
                    1, wrappedTrack));
                wasInserted = 1;
                break;
            }
        }

        if (!wasInserted)
        {
            CHK_OFAIL(mxf_append_list_element(&sortedWrappedTracks, wrappedTrack));
        }
    }
    /* set the MXFTracks to the same order */
    prevSortedWrappedTrack = NULL;
    firstSortedWrappedTrack = NULL;
    mxf_initialise_list_iter(&sortedListIter, &sortedWrappedTracks);
    while (mxf_next_list_iter_element(&sortedListIter))
    {
        sortedWrappedTrack = (WrappedTrack*)mxf_get_iter_element(&sortedListIter);
        if (firstSortedWrappedTrack == NULL)
        {
            firstSortedWrappedTrack = sortedWrappedTrack;
        }
        if (prevSortedWrappedTrack != NULL)
        {
            prevSortedWrappedTrack->track->next = sortedWrappedTrack->track;
        }
        prevSortedWrappedTrack = sortedWrappedTrack;
    }
    if (prevSortedWrappedTrack != NULL)
    {
        prevSortedWrappedTrack->track->next = NULL;
    }
    if (firstSortedWrappedTrack != NULL)
    {
        reader->clip.tracks = firstSortedWrappedTrack->track;
    }


    /* process source package tracks and linked descriptors */

    mxf_initialise_list_iter(&sortedListIter, &sortedWrappedTracks);
    while (mxf_next_list_iter_element(&sortedListIter))
    {
        sortedWrappedTrack = (WrappedTrack*)mxf_get_iter_element(&sortedListIter);

        CHK_OFAIL(mxf_uu_get_referenced_track(data->headerMetadata, &sortedWrappedTrack->sourcePackageUID,
            sortedWrappedTrack->sourceTrackID, &sourcePackageTrackSet));

        CHK_OFAIL(add_essence_track(essenceReader, &essenceTrack));

        essenceTrack->isVideo = sortedWrappedTrack->isVideo;

        if (mxf_have_item(sourcePackageTrackSet, &MXF_ITEM_K(GenericTrack, TrackNumber)))
        {
            CHK_OFAIL(mxf_get_uint32_item(sourcePackageTrackSet, &MXF_ITEM_K(GenericTrack, TrackNumber), &essenceTrack->trackNumber));
        }
        else
        {
            essenceTrack->trackNumber = 0;
        }
        CHK_OFAIL(mxf_get_uint32_item(sourcePackageTrackSet, &MXF_ITEM_K(GenericTrack, TrackID), &trackID));

        essenceTrack->frameRate = reader->clip.frameRate;
        essenceTrack->playoutDuration = reader->clip.duration;

        essenceTrack->indexSID = data->indexSID;
        essenceTrack->bodySID = data->bodySID;

        /* process the descriptor */

        CHK_OFAIL(mxf_uu_get_referenced_package(data->headerMetadata, &sortedWrappedTrack->sourcePackageUID,
            &sourcePackageSet));
        CHK_OFAIL(mxf_uu_get_track_descriptor(sourcePackageSet, trackID, &descriptorSet));

        if (mxf_is_subclass_of(data->headerMetadata->dataModel, &descriptorSet->key, &MXF_SET_K(CDCIEssenceDescriptor)))
        {
            CHK_OFAIL(process_cdci_descriptor(descriptorSet, sortedWrappedTrack->track, essenceTrack));
        }
        else if (mxf_is_subclass_of(data->headerMetadata->dataModel, &descriptorSet->key, &MXF_SET_K(WaveAudioDescriptor)))
        {
            CHK_OFAIL(process_wav_descriptor(descriptorSet, sortedWrappedTrack->track, essenceTrack));
        }
        else if (mxf_is_subclass_of(data->headerMetadata->dataModel, &descriptorSet->key, &MXF_SET_K(GenericSoundEssenceDescriptor)))
        {
            CHK_OFAIL(process_sound_descriptor(descriptorSet, track, essenceTrack));
        }
        else
        {
            mxf_log_error("Unsupported file descriptor" LOG_LOC_FORMAT, LOG_LOC_PARAMS);
            return 0;
        }
    }


    /* initialise the playout timecode */

    if (!initialise_playout_timecode(reader, materialPackageSet))
    {
        CHK_ORET(initialise_default_playout_timecode(reader));
    }


    /* initialise the source timecodes */

    initialise_source_timecodes(reader, sourcePackageSet);



    mxf_clear_list(&wrappedTracks);
    mxf_clear_list(&sortedWrappedTracks);
    return 1;

fail:
    SAFE_FREE(newWrappedTrack);
    mxf_clear_list(&wrappedTracks);
    mxf_clear_list(&sortedWrappedTracks);
    return 0;
}
コード例 #6
0
static int ns_position_at_first_frame(MXFReader *reader)
{
    MXFFile *mxfFile = reader->mxfFile;
    EssenceReader *essenceReader = reader->essenceReader;
    EssenceReaderData *data = essenceReader->data;
    NSFileIndex *nsIndex = &data->nsIndex;
    MXFPartition *partition = data->headerPartition;
    mxfKey key;
    uint8_t llen;
    uint64_t len;

    /* move to the first partition that contains essence data */
    while (data->bodySID != partition->bodySID)
    {
        if (!mxf_read_kl(mxfFile, &key, &llen, &len))
        {
            CHK_OFAIL(mxf_file_eof(mxfFile));
            ns_set_next_kl(nsIndex, &g_Null_Key, 0, 0);
            return 1;
        }
        while (!mxf_is_partition_pack(&key))
        {
            CHK_OFAIL(mxf_skip(mxfFile, len));
            if (!mxf_read_kl(mxfFile, &key, &llen, &len))
            {
                CHK_OFAIL(mxf_file_eof(mxfFile));
                ns_set_next_kl(nsIndex, &g_Null_Key, 0, 0);
                return 1;
            }
        }
        if (partition != NULL && partition != data->headerPartition)
        {
            mxf_free_partition(&partition);
        }
        CHK_OFAIL(mxf_read_partition(mxfFile, &key, &partition));
    }

    /* move to start of essence data in partition */

    /* if we are in the header partition then the file is positioned after the header metadata,
       otherwise we are positioned after the partition pack that was just read */
    if (partition != data->headerPartition)
    {
        /* skip initial filler which is not included in any header or index byte counts */
        if (!mxf_read_next_nonfiller_kl(mxfFile, &key, &llen, &len))
        {
            CHK_ORET(mxf_file_eof(mxfFile));
            ns_set_next_kl(nsIndex, &g_Null_Key, 0, 0);
            return 1;
        }

        /* skip header metadata */
        if (partition->headerByteCount > 0)
        {
            CHK_ORET(mxf_skip(mxfFile, partition->headerByteCount - mxfKey_extlen - llen));
            if (!mxf_read_kl(mxfFile, &key, &llen, &len))
            {
                CHK_ORET(mxf_file_eof(mxfFile));
                ns_set_next_kl(nsIndex, &g_Null_Key, 0, 0);
                return 1;
            }
        }
        else
        {
            CHK_ORET(!mxf_is_header_metadata(&key));
        }
    }
    else
    {
        if (!mxf_read_kl(mxfFile, &key, &llen, &len))
        {
            CHK_ORET(mxf_file_eof(mxfFile));
            ns_set_next_kl(nsIndex, &g_Null_Key, 0, 0);
            return 1;
        }
    }


    /* skip index table segments. Note: we are not checking for segment key because it
       could be non-standard, eg. MXF V10 indexes */
    if (partition->indexByteCount > 0)
    {
        CHK_ORET(mxf_skip(mxfFile, partition->indexByteCount - mxfKey_extlen - llen));
        if (!mxf_read_kl(mxfFile, &key, &llen, &len))
        {
            CHK_ORET(mxf_file_eof(mxfFile));
            ns_set_next_kl(nsIndex, &g_Null_Key, 0, 0);
            return 1;
        }
    }

    /* check the first essence element KL and position after */
    CHK_ORET(mxf_is_gc_essence_element(&key));
    if (mxf_equals_key(&nsIndex->startContentPackageKey, &g_Null_Key))
    {
        nsIndex->startContentPackageKey = key;
        nsIndex->currentPosition = 0;
    }
    else
    {
        CHK_ORET(mxf_equals_key(&nsIndex->startContentPackageKey, &key));
    }
    ns_set_next_kl(nsIndex, &key, llen, len);

    if (partition != NULL && partition != data->headerPartition)
    {
        mxf_free_partition(&partition);
    }
    return 1;

fail:
    if (partition != NULL && partition != data->headerPartition)
    {
        mxf_free_partition(&partition);
    }
    return 0;
}