예제 #1
0
파일: test_file.c 프로젝트: DraFFty/libMXF
int test_modify(const char* filename)
{
    MXFFile* mxfFile = NULL;
    
    
    if (!mxf_disk_file_open_modify(filename, &mxfFile))
    {
        mxf_log_error("Failed to open modify '%s'" LOG_LOC_FORMAT, filename, LOG_LOC_PARAMS);
        return 0;
    }

    /* TEST */

    CHK_OFAIL(do_write(mxfFile));
    
    mxf_file_close(&mxfFile);
    
    CHK_OFAIL(test_read(filename));
    
    return 1;
    
fail:
    mxf_file_close(&mxfFile);
    return 0;
}
예제 #2
0
int mxf_read_rip_and_size(MXFFile *mxfFile, MXFRIP *rip, uint32_t* size)
{
	uint32_t rip_size;
    mxfKey key;
    uint8_t llen;
    uint64_t len;
    uint32_t numEntries;
    MXFRIPEntry *newEntry = NULL;
    MXFRIPEntry *entry;
    uint32_t i;

    mxf_initialise_list(&rip->entries, free);

    /* read RIP size (min is 16 + 1 + (4 + 8) * 1 + 4) at end of file */
    if (!mxf_file_seek(mxfFile, -4, SEEK_END) ||
        !mxf_read_uint32(mxfFile, &rip_size) ||
        rip_size < 33)
    {
        return 0;
    }

    /* seek, read and check RIP key */
    if (!mxf_file_seek(mxfFile, (int64_t)0 - rip_size, SEEK_CUR) ||
        !mxf_read_k(mxfFile, &key) ||
        !mxf_equals_key(&key, &g_RandomIndexPack_key) ||
        !mxf_read_l(mxfFile, &llen, &len))
    {
        return 0;
    }

    /* read RIP */

    numEntries = ((uint32_t)len - 4) / 12;
    CHK_ORET(((uint32_t)len - 4) % 12 == 0);

    for (i = 0; i < numEntries; i++)
    {
        CHK_MALLOC_OFAIL(newEntry, MXFRIPEntry);
        CHK_OFAIL(mxf_append_list_element(&rip->entries, newEntry));
        entry = newEntry;
        newEntry = NULL; /* entry assigned to list so set to NULL so not free'ed in fail */
        CHK_OFAIL(mxf_read_uint32(mxfFile, &entry->bodySID));
        CHK_OFAIL(mxf_read_uint64(mxfFile, &entry->thisPartition));
    }

	*size = rip_size;
    return 1;

fail:
    if (newEntry != NULL)
    {
        free(newEntry);
    }
    mxf_clear_list(&rip->entries);
    return 0;
}
예제 #3
0
int hac_create_http_access(MediaPlayer* player, int port, HTTPAccess** access)
{
    HTTPAccess* newAccess;

    CALLOC_ORET(newAccess, HTTPAccess, 1);

    CHK_OFAIL(har_create_resources(&newAccess->resources));

    newAccess->control = ply_get_media_control(player);
    if (newAccess->control == NULL)
    {
        fprintf(stderr, "Media player has no control\n");
        goto fail;
    }

    newAccess->playerListener.data = newAccess;
    newAccess->playerListener.frame_displayed_event = hac_frame_displayed_event;
    newAccess->playerListener.frame_dropped_event = hac_frame_dropped_event;
    newAccess->playerListener.state_change_event = hac_state_change_event;
    newAccess->playerListener.end_of_source_event = hac_end_of_source_event;
    newAccess->playerListener.start_of_source_event = hac_start_of_source_event;
    newAccess->playerListener.player_closed = hac_player_closed;

    if (!ply_register_player_listener(player, &newAccess->playerListener))
    {
        fprintf(stderr, "Failed to register http access as player listener\n");
        goto fail;
    }

    CHK_OFAIL((newAccess->ctx = shttpd_init(NULL, "document_root", "/dev/null", NULL)) != NULL);
    shttpd_register_uri(newAccess->ctx, "/", &http_player_page, newAccess);
    shttpd_register_uri(newAccess->ctx, "/player.html", &http_player_page, newAccess);
    shttpd_register_uri(newAccess->ctx, "/index.html", &http_player_page, newAccess);
    shttpd_register_uri(newAccess->ctx, "/resources/*", &http_static_content, newAccess);
    shttpd_register_uri(newAccess->ctx, "/player/state.xml", &http_player_state_xml, newAccess);
    shttpd_register_uri(newAccess->ctx, "/player/state.txt", &http_player_state_txt, newAccess);
    shttpd_register_uri(newAccess->ctx, "/player/control/*", &http_player_control, newAccess);
    CHK_OFAIL(shttpd_listen(newAccess->ctx, port, 0));


    CHK_OFAIL(init_mutex(&newAccess->playerStateMutex));
    CHK_OFAIL(create_joinable_thread(&newAccess->httpThreadId, http_thread, newAccess));


    *access = newAccess;
    return 1;

fail:
    hac_free_http_access(&newAccess);
    return 0;
}
예제 #4
0
파일: blank_source.c 프로젝트: dluobo/ingex
int bks_create(const StreamInfo* videoStreamInfo, int64_t length, MediaSource** source)
{
    BlankSource* newSource = NULL;

    if (videoStreamInfo->type != PICTURE_STREAM_TYPE)
    {
        ml_log_error("Blank source only does video\n");
        return 0;
    }


    CALLOC_ORET(newSource, BlankSource, 1);

    newSource->length = length;

    newSource->mediaSource.data = newSource;
    newSource->mediaSource.finalise_blank_source = bks_finalise_blank_source;
    newSource->mediaSource.get_num_streams = bks_get_num_streams;
    newSource->mediaSource.get_stream_info = bks_get_stream_info;
    newSource->mediaSource.set_frame_rate_or_disable = bks_set_frame_rate_or_disable;
    newSource->mediaSource.disable_stream = bks_disable_stream;
    newSource->mediaSource.disable_video = bks_disable_video;
    newSource->mediaSource.stream_is_disabled = bks_stream_is_disabled;
    newSource->mediaSource.read_frame = bks_read_frame;
    newSource->mediaSource.is_seekable = bks_is_seekable;
    newSource->mediaSource.seek = bks_seek;
    newSource->mediaSource.get_length = bks_get_length;
    newSource->mediaSource.get_position = bks_get_position;
    newSource->mediaSource.get_available_length = bks_get_available_length;
    newSource->mediaSource.eof = bks_eof;
    newSource->mediaSource.set_source_name = bks_set_source_name;
    newSource->mediaSource.set_clip_id = bks_set_clip_id;
    newSource->mediaSource.close = bks_close;

    newSource->streamInfo = *videoStreamInfo;
    newSource->streamInfo.sourceId = msc_create_id();

    CHK_OFAIL(add_known_source_info(&newSource->streamInfo, SRC_INFO_TITLE, "Blank Source"));
    CHK_OFAIL(add_known_source_info(&newSource->streamInfo, SRC_INFO_ORIGINAL_STREAM_FORMAT,
                                    get_stream_format_string(newSource->streamInfo.format)));


    *source = &newSource->mediaSource;
    return 1;

fail:
    bks_close(newSource);
    return 0;
}
예제 #5
0
static int append_name_to_string_array(MXFMetadataSet* set, const mxfKey* itemKey, const mxfUTF16Char* name)
{
    uint8_t* nameArray = NULL;
    uint16_t existingNameArraySize = 0;
    uint16_t nameArraySize = 0;
    MXFMetadataItem* namesItem = NULL;
    
    if (mxf_have_item(set, itemKey))
    {
        CHK_ORET(mxf_get_item(set, itemKey, &namesItem));
        existingNameArraySize = namesItem->length;
    }
    nameArraySize = existingNameArraySize + (uint16_t)(mxfUTF16Char_extlen * (wcslen(name) + 1));
    
    CHK_MALLOC_ARRAY_ORET(nameArray, uint8_t, nameArraySize);
    if (existingNameArraySize > 0)
    {
        memcpy(nameArray, namesItem->value, existingNameArraySize);
    }
    mxf_set_utf16string(name, &nameArray[existingNameArraySize]);
    
    CHK_OFAIL(mxf_set_item(set, itemKey, nameArray, nameArraySize));

    SAFE_FREE(&nameArray);
    return 1;
    
fail:
    SAFE_FREE(&nameArray);
    return 0;
}
예제 #6
0
static int init_display(X11DisplaySink* sink, const StreamInfo* streamInfo)
{
    if (!sink->displayInitialised)
    {
        CHK_OFAIL(x11c_prepare_display(&sink->x11Common));
    }

    sink->inputWidth = streamInfo->width;
    sink->inputHeight = streamInfo->height;

    sink->width = sink->inputWidth / sink->swScale;
    sink->height = sink->inputHeight / sink->swScale;

    sink->aspectRatio.num = 4;
    sink->aspectRatio.den = 3;
    sink->displayWidth = sink->width;
    sink->displayHeight = sink->height;

    if (streamInfo->format == UYVY_FORMAT ||
        streamInfo->format == UYVY_10BIT_FORMAT)
    {
        sink->yuvFormat = UYVY;
    }
    else if (streamInfo->format == YUV422_FORMAT)
    {
        sink->yuvFormat = YV16;
    }
    else /* streamInfo->format == YUV420_FORMAT */
    {
        sink->yuvFormat = I420;
    }

    /* check if we can use shared memory */
    sink->useSharedMemory = x11c_shared_memory_available(&sink->x11Common);

    CHK_OFAIL(x11c_init_window(&sink->x11Common, sink->displayWidth, sink->displayHeight, sink->width, sink->height));

    sink->displayInitialised = 1;
    sink->displayInitFailed = 0;
    return 1;

fail:
    sink->displayInitialised = 0;
    sink->displayInitFailed = 1;
    return 0;
}
예제 #7
0
int is_archive_mxf(MXFHeaderMetadata* headerMetadata)
{
    MXFMetadataSet* prefaceSet;
    MXFArrayItemIterator arrayIter;
    uint8_t* arrayElement;
    uint32_t arrayElementLen;
    int haveBBCScheme = 0;
    mxfUL ul;
    
    CHK_OFAIL(mxf_find_singular_set_by_key(headerMetadata, &MXF_SET_K(Preface), &prefaceSet));

    /* check is OP-1A */
    CHK_OFAIL(mxf_get_ul_item(prefaceSet, &MXF_ITEM_K(Preface, OperationalPattern), &ul));
    if (!is_op_1a(&ul))
    {
        return 0;
    }

    
    /* check BBC descriptive metadata scheme */
    if (mxf_have_item(prefaceSet, &MXF_ITEM_K(Preface, DMSchemes)))
    {
        CHK_OFAIL(mxf_initialise_array_item_iterator(prefaceSet, &MXF_ITEM_K(Preface, DMSchemes), &arrayIter));
        while (mxf_next_array_item_element(&arrayIter, &arrayElement, &arrayElementLen))
        {
            mxf_get_ul(arrayElement, &ul);
            if (mxf_equals_ul(&ul, &MXF_DM_L(APP_PreservationDescriptiveScheme)))
            {
                haveBBCScheme = 1;
                break;
            }
        }
    }
    if (!haveBBCScheme)
    {
        return 0;
    }


    return 1;    
    
fail:
    return 0;    
}
예제 #8
0
int mxf_open_essence_element_write(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));

    CHK_OFAIL((filePos = mxf_file_tell(mxfFile)) >= 0);
    newEssenceElement->startFilePos = filePos;
    newEssenceElement->currentFilePos = newEssenceElement->startFilePos;
    CHK_OFAIL(mxf_write_k(mxfFile, key));
    CHK_OFAIL(mxf_write_fixed_l(mxfFile, llen, len));

    *essenceElement = newEssenceElement;
    return 1;

fail:
    SAFE_FREE(newEssenceElement);
    return 0;
}
예제 #9
0
int mxf_create_set(MXFHeaderMetadata* headerMetadata, const mxfKey* key, MXFMetadataSet** set)
{
    MXFMetadataSet* newSet;
    mxfUUID uuid;
    
    CHK_ORET(create_empty_set(key, &newSet));
    
    mxf_generate_uuid(&uuid);
    newSet->instanceUID = uuid;

    CHK_OFAIL(mxf_add_set(headerMetadata, newSet));

    CHK_OFAIL(mxf_set_uuid_item(newSet, &MXF_ITEM_K(InterchangeObject, InstanceUID), &uuid));
    
    *set = newSet;
    return 1;
    
fail:
    mxf_free_set(&newSet);
    return 0;
}
예제 #10
0
int mxf_append_partition_esscont_label(MXFPartition *partition, const mxfUL *label)
{
    mxfUL *newLabel;

    CHK_MALLOC_ORET(newLabel, mxfUL);
    *newLabel = *label;
    CHK_OFAIL(mxf_append_list_element(&partition->essenceContainers, newLabel));

    return 1;

fail:
    SAFE_FREE(newLabel);
    return 0;
}
예제 #11
0
int mxf_append_new_partition(MXFFilePartitions *partitions, MXFPartition **partition)
{
    MXFPartition *newPartition;

    CHK_ORET(mxf_create_partition(&newPartition));
    CHK_OFAIL(mxf_append_partition(partitions, newPartition));

    *partition = newPartition;
    return 1;

fail:
    mxf_free_partition(&newPartition);
    return 0;
}
예제 #12
0
int mxf_create_header_metadata(MXFHeaderMetadata** headerMetadata, MXFDataModel* dataModel)
{
    MXFHeaderMetadata* newHeaderMetadata;
    
    CHK_MALLOC_ORET(newHeaderMetadata, MXFHeaderMetadata);
    memset(newHeaderMetadata, 0, sizeof(MXFHeaderMetadata));
    newHeaderMetadata->dataModel = dataModel;
    mxf_initialise_list(&newHeaderMetadata->sets, free_metadata_set_in_list);
    CHK_OFAIL(mxf_create_primer_pack(&newHeaderMetadata->primerPack));
    
    *headerMetadata = newHeaderMetadata;
    return 1;   
    
fail:
    mxf_free_header_metadata(&newHeaderMetadata);
    return 0;
}
예제 #13
0
static int add_metadef_to_list(MXFList* list, const mxfUL* identification, const mxfUUID* instanceUID)
{
    MetaDefData* data = NULL;
    
    CHK_MALLOC_ORET(data, MetaDefData);
    data->identification = *identification;
    data->instanceUID = *instanceUID;
    
    CHK_OFAIL(mxf_append_list_element(list, (void*)data));
    data = NULL;
    
    return 1;
    
fail:
    SAFE_FREE(&data);
    return 0;
}
예제 #14
0
int mxf_page_file_open_new(const char *filenameTemplate, int64_t pageSize, MXFPageFile **mxfPageFile)
{
    MXFFile *newMXFFile = NULL;

    if (strstr(filenameTemplate, "%d") == NULL)
    {
        mxf_log_error("Filename template '%s' doesn't contain %%d\n", filenameTemplate);
        return 0;
    }

    CHK_MALLOC_ORET(newMXFFile, MXFFile);
    memset(newMXFFile, 0, sizeof(*newMXFFile));

    newMXFFile->close           = page_file_close;
    newMXFFile->read            = page_file_read;
    newMXFFile->write           = page_file_write;
    newMXFFile->get_char        = page_file_getchar;
    newMXFFile->put_char        = page_file_putchar;
    newMXFFile->eof             = page_file_eof;
    newMXFFile->seek            = page_file_seek;
    newMXFFile->tell            = page_file_tell;
    newMXFFile->is_seekable     = page_file_is_seekable;
    newMXFFile->size            = page_file_size;
    newMXFFile->free_sys_data   = free_page_file;


    CHK_MALLOC_OFAIL(newMXFFile->sysData, MXFFileSysData);
    memset(newMXFFile->sysData, 0, sizeof(*newMXFFile->sysData));

    CHK_OFAIL((newMXFFile->sysData->filenameTemplate = strdup(filenameTemplate)) != NULL);
    newMXFFile->sysData->pageSize = pageSize;
    newMXFFile->sysData->mode = WRITE_MODE;
    newMXFFile->sysData->mxfPageFile.mxfFile = newMXFFile;


    *mxfPageFile = &newMXFFile->sysData->mxfPageFile;
    return 1;

fail:
    if (newMXFFile != NULL)
    {
        mxf_file_close(&newMXFFile);
    }
    return 0;
}
예제 #15
0
static int add_weakref_to_list(MXFList* list, MXFMetadataItem* item, int arrayIndex, const mxfUL* targetIdentification)
{
    WeakRefData* data = NULL;
    
    CHK_MALLOC_ORET(data, WeakRefData);
    data->item = item;
    data->arrayIndex = arrayIndex;
    data->targetIdentification = *targetIdentification;
    
    CHK_OFAIL(mxf_append_list_element(list, (void*)data));
    data = NULL;
    
    return 1;
    
fail:
    SAFE_FREE(&data);
    return 0;
}
예제 #16
0
int mxf_create_item(MXFMetadataSet* set, const mxfKey* key, mxfLocalTag tag, MXFMetadataItem** item)
{
    MXFMetadataItem* newItem;
    
    CHK_MALLOC_ORET(newItem, MXFMetadataItem);
    memset(newItem, 0, sizeof(MXFMetadataItem));
    newItem->tag = tag;
    newItem->isPersistent = 0;
    newItem->key = *key;

    CHK_OFAIL(add_item(set, newItem));
    
    *item = newItem;
    return 1;

fail:
    mxf_free_item(&newItem);
    return 0;
}
예제 #17
0
int sts_create(int64_t startTimecode, const Rational* startTimecodeFrameRate, MediaSource** source)
{
    SystemTimecodeSource* newSource = NULL;

    CALLOC_ORET(newSource, SystemTimecodeSource, 1);

    newSource->startTimecode = startTimecode;
    newSource->length = 0x7fffffffffffffffLL;

    newSource->mediaSource.data = newSource;
    newSource->mediaSource.get_num_streams = sts_get_num_streams;
    newSource->mediaSource.get_stream_info = sts_get_stream_info;
    newSource->mediaSource.set_frame_rate_or_disable = sts_set_frame_rate_or_disable;
    newSource->mediaSource.disable_stream = sts_disable_stream;
    newSource->mediaSource.stream_is_disabled = sts_stream_is_disabled;
    newSource->mediaSource.read_frame = sts_read_frame;
    newSource->mediaSource.is_seekable = sts_is_seekable;
    newSource->mediaSource.seek = sts_seek;
    newSource->mediaSource.get_length = sts_get_length;
    newSource->mediaSource.get_position = sts_get_position;
    newSource->mediaSource.get_available_length = sts_get_available_length;
    newSource->mediaSource.eof = sts_eof;
    newSource->mediaSource.set_source_name = sts_set_source_name;
    newSource->mediaSource.set_clip_id = sts_set_clip_id;
    newSource->mediaSource.close = sts_close;

    CHK_OFAIL(initialise_stream_info(&newSource->streamInfo));
    newSource->streamInfo.type = TIMECODE_STREAM_TYPE;
    newSource->streamInfo.format = TIMECODE_FORMAT;
    newSource->streamInfo.frameRate = *startTimecodeFrameRate;
    newSource->streamInfo.isHardFrameRate = 0;
    newSource->streamInfo.format = TIMECODE_FORMAT;
    newSource->streamInfo.sourceId = msc_create_id();
    newSource->streamInfo.timecodeType = SYSTEM_TIMECODE_TYPE;
    newSource->streamInfo.timecodeSubType = NO_TIMECODE_SUBTYPE;

    *source = &newSource->mediaSource;
    return 1;

fail:
    sts_close(newSource);
    return 0;
}
예제 #18
0
int mxf_find_singular_set_by_key(MXFHeaderMetadata* headerMetadata, const mxfKey* key, MXFMetadataSet** set)
{
    MXFList* setList = NULL;

    if (!mxf_find_set_by_key(headerMetadata, key, &setList))
    {
        return 0;
    }
    
    CHK_OFAIL(mxf_get_list_length(setList) == 1);

    *set = (MXFMetadataSet*)mxf_get_first_list_element(setList);
    
    mxf_free_list(&setList);
    return 1;
    
fail:
    mxf_free_list(&setList);
    return 0;
}
예제 #19
0
파일: xml_writer.c 프로젝트: DraFFty/libMXF
int xml_writer_open(const char* filename, XMLWriter** writer)
{
    XMLWriter* newWriter;
    
    CHK_MALLOC_ORET(newWriter, XMLWriter);
    memset(newWriter, 0, sizeof(XMLWriter));
    newWriter->previousWrite = ELEMENT_END;

    if ((newWriter->file = fopen(filename, "wb")) == NULL)
    {
        mxf_log_error("Failed to open xml file '%s'" LOG_LOC_FORMAT, filename, LOG_LOC_PARAMS);
        goto fail;
    }
    
    CHK_OFAIL(fprintf(newWriter->file, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>") > 0);
    
    *writer = newWriter;
    return 1;
    
fail:
    SAFE_FREE(&newWriter);
    return 0;
}
예제 #20
0
int mxf_find_set_by_key(MXFHeaderMetadata* headerMetadata, const mxfKey* key, MXFList** setList)
{
    MXFListIterator iter;
    MXFList* newList = NULL;

    CHK_ORET(mxf_create_list(&newList, NULL)); /* free func == NULL because newList doesn't own the data */
    
    mxf_initialise_list_iter(&iter, &headerMetadata->sets);
    while (mxf_next_list_iter_element(&iter))
    {
        MXFMetadataSet* set = (MXFMetadataSet*)mxf_get_iter_element(&iter);
        if (mxf_equals_key(key, &set->key))
        {
            CHK_OFAIL(mxf_append_list_element(newList, (void*)set));
        }
    }

    *setList = newList;    
    return 1;
    
fail:
    mxf_free_list(&newList);
    return 0;
}
예제 #21
0
static int archive_mxf_get_package_pse_failures(MXFHeaderMetadata* headerMetadata, MXFMetadataSet* packageSet,
                                                PSEFailure** failures, long* numFailures)
{
    MXFArrayItemIterator arrayIter;
    MXFArrayItemIterator arrayIter2;
    uint8_t* arrayElement;
    uint32_t arrayElementLen;
    mxfUL dataDef;
    uint32_t count;
    MXFMetadataSet* packageTrackSet;
    MXFMetadataSet* sequenceSet;
    MXFMetadataSet* dmSet;
    MXFMetadataSet* dmFrameworkSet;
    MXFListIterator setsIter;
    PSEFailure* newFailures = NULL;
    long countedPSEFailures = 0;
    PSEFailure* tmp;
    int32_t i;
    

    CHK_OFAIL(mxf_uu_get_package_tracks(packageSet, &arrayIter));
    while (mxf_uu_next_track(headerMetadata, &arrayIter, &packageTrackSet))
    {
        CHK_OFAIL(mxf_uu_get_track_datadef(packageTrackSet, &dataDef));
        if (mxf_is_descriptive_metadata(&dataDef))
        {
            /* get to the sequence */
            CHK_OFAIL(mxf_get_strongref_item(packageTrackSet, &MXF_ITEM_K(GenericTrack, Sequence), &sequenceSet));
            if (mxf_is_subclass_of(headerMetadata->dataModel, &sequenceSet->key, &MXF_SET_K(Sequence)))
            {
                CHK_OFAIL(mxf_get_array_item_count(sequenceSet, &MXF_ITEM_K(Sequence, StructuralComponents), &count));
                if (count == 0)
                {
                    continue;
                }
                
                CHK_OFAIL(mxf_get_array_item_element(sequenceSet, &MXF_ITEM_K(Sequence, StructuralComponents), 0, &arrayElement));
                CHK_OFAIL(mxf_get_strongref(headerMetadata, arrayElement, &dmSet));
            }
            else
            {
                dmSet = sequenceSet;
            }
            
            /* if it is a DMSegment with a DMFramework reference then we have the DMS track */
            if (mxf_is_subclass_of(headerMetadata->dataModel, &dmSet->key, &MXF_SET_K(DMSegment)))
            {
                if (mxf_have_item(dmSet, &MXF_ITEM_K(DMSegment, DMFramework)))
                {
                    CHK_OFAIL(mxf_get_strongref_item(dmSet, &MXF_ITEM_K(DMSegment, DMFramework), &dmFrameworkSet));

                    /* check whether the DMFrameworkSet is a APP_PSEAnalysisFramework */                   
                    if (mxf_is_subclass_of(headerMetadata->dataModel, &dmFrameworkSet->key, &MXF_SET_K(APP_PSEAnalysisFramework)))
                    {
                        /* go back to the sequence and extract the PSE failures */
                        
                        CHK_OFAIL(mxf_get_array_item_count(sequenceSet, &MXF_ITEM_K(Sequence, StructuralComponents), &count));
                        countedPSEFailures += count;
                        if (newFailures == NULL)
                        {
                            CHK_OFAIL((tmp = malloc(sizeof(PSEFailure) * countedPSEFailures)) != NULL);
                        }
                        else
                        {
                            /* multiple tracks with PSE failures - reallocate the array */
                            CHK_OFAIL((tmp = realloc(newFailures, sizeof(PSEFailure) * countedPSEFailures)) != NULL);
                        }
                        newFailures = tmp;
                        
                        /* extract the PSE failures */
                        initialise_sets_iter(headerMetadata, &setsIter);
                        i = 0;
                        mxf_initialise_array_item_iterator(sequenceSet, &MXF_ITEM_K(Sequence, StructuralComponents), &arrayIter2);
                        while (mxf_next_array_item_element(&arrayIter2, &arrayElement, &arrayElementLen))
                        {
                            PSEFailure* pseFailure = &newFailures[i];
                            
                            CHK_OFAIL(mxf_get_strongref_s(headerMetadata, &setsIter, arrayElement, &dmSet));
                            CHK_OFAIL(mxf_get_position_item(dmSet, &MXF_ITEM_K(DMSegment, EventStartPosition), &pseFailure->position));
                            CHK_OFAIL(mxf_get_strongref_item_s(&setsIter, dmSet, &MXF_ITEM_K(DMSegment, DMFramework), &dmFrameworkSet));
                            CHK_OFAIL(mxf_get_int16_item(dmFrameworkSet, &MXF_ITEM_K(APP_PSEAnalysisFramework, APP_RedFlash), &pseFailure->redFlash));
                            CHK_OFAIL(mxf_get_int16_item(dmFrameworkSet, &MXF_ITEM_K(APP_PSEAnalysisFramework, APP_SpatialPattern), &pseFailure->spatialPattern));
                            CHK_OFAIL(mxf_get_int16_item(dmFrameworkSet, &MXF_ITEM_K(APP_PSEAnalysisFramework, APP_LuminanceFlash), &pseFailure->luminanceFlash));
                            CHK_OFAIL(mxf_get_boolean_item(dmFrameworkSet, &MXF_ITEM_K(APP_PSEAnalysisFramework, APP_ExtendedFailure), &pseFailure->extendedFailure));
                            i++;
                        }
                        break;
                    }
                }
            }
        }
    }
    
    *failures = newFailures;
    *numFailures = countedPSEFailures;
    return 1;

fail:
    SAFE_FREE(&newFailures);
    return 0;
}
예제 #22
0
/* Read primer pack followed by sets. The inputs pkey, pllen, plen must 
   correspond to that for the primer pack */
int mxf_read_filtered_header_metadata(MXFFile* mxfFile, MXFReadFilter* filter, 
    MXFHeaderMetadata* headerMetadata, uint64_t headerByteCount, 
    const mxfKey* pkey, uint8_t pllen, uint64_t plen)
{
    mxfKey key;
    uint8_t llen;
    uint64_t len;    
    int skip = 0;
    MXFMetadataSet* newSet = NULL;
    uint64_t count = 0;
    int result;

    CHK_ORET(headerByteCount != 0);
    
    /* check that input pkey is as expected, and assume pllen and plen are also ok */
    CHK_ORET(mxf_is_primer_pack(pkey));  
    count += mxfKey_extlen + pllen;
    
    if (headerMetadata->primerPack != NULL)
    {
        mxf_free_primer_pack(&headerMetadata->primerPack);
    }
    CHK_ORET(mxf_read_primer_pack(mxfFile, &headerMetadata->primerPack));
    count += plen;
    
    while (count < headerByteCount)
    {
        CHK_ORET(mxf_read_kl(mxfFile, &key, &llen, &len));
        count += mxfKey_extlen + llen;
        
        if (mxf_is_filler(&key))
        {
            CHK_ORET(mxf_skip(mxfFile, len));
        }
        else
        {
            if (filter != NULL)
            {
                /* signal before read */
                skip = 0;
                if (filter->before_set_read != NULL)
                {
                    CHK_ORET(filter->before_set_read(filter->privateData, headerMetadata, &key, llen, len, &skip));
                }
                
                if (!skip)
                {
                    CHK_ORET((result = mxf_read_and_return_set(mxfFile, &key, len, headerMetadata, 0, &newSet)) > 0);

                    if (result == 1) /* set was read and returned in "set" parameter */
                    {
                        /* signal after read */
                        skip = 0;
                        if (filter->after_set_read != NULL)
                        {
                            CHK_OFAIL(filter->after_set_read(filter->privateData, headerMetadata, newSet, &skip));
                        }
                        
                        if (!skip)
                        {
                            CHK_OFAIL(mxf_add_set(headerMetadata, newSet));
                        }
                        else
                        {
                            mxf_free_set(&newSet);
                        }
                    }
                }
                else
                {
                    CHK_ORET(mxf_skip(mxfFile, len));
                }
            }
            else
            {
                CHK_ORET(mxf_read_set(mxfFile, &key, len, headerMetadata, 1) > 0);
            }
        }
        count += len;
    }
    CHK_ORET(count == headerByteCount);
    
    return 1;
    
fail:
    mxf_free_set(&newSet);
    return 0;
}
예제 #23
0
int mxf_page_file_open_modify(const char *filenameTemplate, int64_t pageSize, MXFPageFile **mxfPageFile)
{
    MXFFile *newMXFFile = NULL;
    int pageCount;
    int allocatedPages;
    char filename[4096];
    FILE *file;
    int64_t fileSize;


    if (strstr(filenameTemplate, "%d") == NULL)
    {
        mxf_log_error("Filename template '%s' doesn't contain %%d\n", filenameTemplate);
        return 0;
    }

    /* count number of page files */
    pageCount = 0;
    for(;;)
    {
        mxf_snprintf(filename, sizeof(filename), filenameTemplate, pageCount);
        if ((file = fopen(filename, "rb")) == NULL)
        {
            break;
        }
        fclose(file);
        pageCount++;
    }

    if (pageCount == 0)
    {
        /* file not found */
        return 0;
    }

    /* check the size of the first file equals the pageSize */
    if (pageCount > 1)
    {
        mxf_snprintf(filename, sizeof(filename), filenameTemplate, 0);
        fileSize = disk_file_size(filename);
        if (fileSize < 0)
        {
            mxf_log_error("Failed to stat file '%s': %s\n", filename, strerror(errno));
            return 0;
        }
        if (pageSize != fileSize)
        {
            mxf_log_error("Size of first file '%s' (%"PRId64" does not equal page size %"PRId64"\n", filename, fileSize, pageSize);
            return 0;
        }
    }


    CHK_MALLOC_ORET(newMXFFile, MXFFile);
    memset(newMXFFile, 0, sizeof(*newMXFFile));

    newMXFFile->close           = page_file_close;
    newMXFFile->read            = page_file_read;
    newMXFFile->write           = page_file_write;
    newMXFFile->get_char        = page_file_getchar;
    newMXFFile->put_char        = page_file_putchar;
    newMXFFile->eof             = page_file_eof;
    newMXFFile->seek            = page_file_seek;
    newMXFFile->tell            = page_file_tell;
    newMXFFile->is_seekable     = page_file_is_seekable;
    newMXFFile->size            = page_file_size;
    newMXFFile->free_sys_data   = free_page_file;


    CHK_MALLOC_OFAIL(newMXFFile->sysData, MXFFileSysData);
    memset(newMXFFile->sysData, 0, sizeof(*newMXFFile->sysData));

    CHK_OFAIL((newMXFFile->sysData->filenameTemplate = strdup(filenameTemplate)) != NULL);
    newMXFFile->sysData->pageSize = pageSize;
    newMXFFile->sysData->mode = MODIFY_MODE;
    newMXFFile->sysData->mxfPageFile.mxfFile = newMXFFile;


    /* allocate pages */
    allocatedPages = (pageCount < PAGE_ALLOC_INCR) ? PAGE_ALLOC_INCR : pageCount;
    CHK_MALLOC_ARRAY_ORET(newMXFFile->sysData->pages, Page, allocatedPages);
    memset(newMXFFile->sysData->pages, 0, allocatedPages * sizeof(Page));
    newMXFFile->sysData->numPages = pageCount;
    newMXFFile->sysData->numPagesAllocated = allocatedPages;
    for (pageCount = 0; pageCount < newMXFFile->sysData->numPages; pageCount++)
    {
        newMXFFile->sysData->pages[pageCount].index = pageCount;
        newMXFFile->sysData->pages[pageCount].size = pageSize;
    }

    /* set the files size of the last file, which could have size < pageSize */
    mxf_snprintf(filename, sizeof(filename), filenameTemplate, newMXFFile->sysData->numPages - 1);
    fileSize = disk_file_size(filename);
    if (fileSize < 0)
    {
        mxf_log_error("Failed to stat file '%s': %s\n", filename, strerror(errno));
        goto fail;
    }
    newMXFFile->sysData->pages[newMXFFile->sysData->numPages - 1].size = fileSize;


    *mxfPageFile = &newMXFFile->sysData->mxfPageFile;
    return 1;

fail:
    if (newMXFFile != NULL)
    {
        mxf_file_close(&newMXFFile);
    }
    return 0;
}
예제 #24
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;
}
예제 #25
0
int test_create_and_write(const char *filename)
{
    MXFFile *mxfFile = NULL;
    uint8_t runin[RUNIN_LEN];
    MXFFilePartitions partitions;
    MXFPartition *headerPartition = NULL;
    MXFPartition *bodyPartition1 = NULL;
    MXFPartition *bodyPartition2 = NULL;
    MXFPartition *footerPartition = NULL;


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

    mxf_initialise_file_partitions(&partitions);

    /* TEST */

    /* write 8 bytes of runin */
    memset(runin, 0, RUNIN_LEN);
    CHK_OFAIL(mxf_file_write(mxfFile, runin, RUNIN_LEN) == RUNIN_LEN);

    /* write the header pp */
    CHK_OFAIL(mxf_append_new_partition(&partitions, &headerPartition));
    headerPartition->key = MXF_PP_K(ClosedComplete, Header);
    headerPartition->indexSID = 1;
    CHK_OFAIL(mxf_append_partition_esscont_label(headerPartition, &MXF_EC_L(SD_Unc_625_50i_422_135_FrameWrapped)));
    CHK_OFAIL(mxf_append_partition_esscont_label(headerPartition, &MXF_EC_L(BWFFrameWrapped)));
    CHK_OFAIL(mxf_write_partition(mxfFile, headerPartition));

    /* write empty header metadata */
    CHK_OFAIL(mxf_mark_header_start(mxfFile, headerPartition));
    CHK_OFAIL(mxf_allocate_space(mxfFile, 1024));
    CHK_OFAIL(mxf_mark_header_end(mxfFile, headerPartition));

    /* write the body pp 1 */
    CHK_OFAIL(mxf_append_new_from_partition(&partitions, headerPartition, &bodyPartition1));
    bodyPartition1->key = MXF_PP_K(ClosedComplete, Body);
    bodyPartition1->bodySID = 2;
    CHK_OFAIL(mxf_write_partition(mxfFile, bodyPartition1));

    /* write the body pp 2, with KAG 256 */
    CHK_OFAIL(mxf_append_new_from_partition(&partitions, headerPartition, &bodyPartition2));
    bodyPartition2->key = MXF_PP_K(ClosedComplete, Body);
    bodyPartition2->bodySID = 3;
    bodyPartition2->kagSize = 256;
    CHK_OFAIL(mxf_write_partition(mxfFile, bodyPartition2));
    CHK_OFAIL(mxf_fill_to_kag(mxfFile, bodyPartition2));

    /* write the footer pp */
    CHK_OFAIL(mxf_append_new_from_partition(&partitions, headerPartition, &footerPartition));
    footerPartition->key = MXF_PP_K(ClosedComplete, Footer);
    footerPartition->indexSID = 1;
    CHK_OFAIL(mxf_write_partition(mxfFile, footerPartition));

    /* write RIP */
    CHK_OFAIL(mxf_write_rip(mxfFile, &partitions));

    /* update the partitions */
    CHK_OFAIL(mxf_update_partitions(mxfFile, &partitions));


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

fail:
    mxf_file_close(&mxfFile);
    mxf_clear_file_partitions(&partitions);
    return 0;
}
예제 #26
0
파일: test_file.c 프로젝트: DraFFty/libMXF
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;
}
예제 #27
0
int archive_mxf_get_info(MXFHeaderMetadata* headerMetadata, ArchiveMXFInfo* info)
{
    MXFList* list = NULL;
    MXFListIterator iter;
    MXFArrayItemIterator arrayIter;
    uint8_t* arrayElement;
    uint32_t arrayElementLen;
    mxfUL dataDef;
    uint32_t count;
    mxfUTF16Char* tempWString = NULL;
    int haveSourceInfaxData = 0;
    MXFList* nameList = NULL;
    MXFList* valueList = NULL;
    MXFMetadataSet* identSet;
    MXFMetadataSet* fileSourcePackageSet;
    MXFMetadataSet* sourcePackageSet;
    MXFMetadataSet* sourcePackageTrackSet;
    MXFMetadataSet* sequenceSet;
    MXFMetadataSet* dmSet;
    MXFMetadataSet* dmFrameworkSet;
    MXFMetadataSet* descriptorSet;
    MXFMetadataSet* locatorSet;
    MXFMetadataSet* materialPackageSet;
    
    
    /* if metadata only then only try reading infax user comments */
    
    if (is_metadata_only_file(headerMetadata, &materialPackageSet))
    {
        if (mxf_avid_read_string_user_comments(materialPackageSet, &nameList, &valueList))
        {
            haveSourceInfaxData = parse_infax_user_comments(nameList, valueList, &info->sourceInfaxData);

            mxf_free_list(&nameList);
            mxf_free_list(&valueList);
        }
        
        return 1;
    }
    
    
    /* Creation timestamp identification info */
    
    CHK_OFAIL(mxf_find_set_by_key(headerMetadata, &MXF_SET_K(Identification), &list));
    mxf_initialise_list_iter(&iter, list);
    if (mxf_next_list_iter_element(&iter))
    {
        identSet = (MXFMetadataSet*)mxf_get_iter_element(&iter);
        CHK_OFAIL(mxf_get_timestamp_item(identSet, &MXF_ITEM_K(Identification, ModificationDate), &info->creationDate));
    }
    mxf_free_list(&list);
    
    
    /* LTO Infax data */    
    
    CHK_OFAIL(mxf_uu_get_top_file_package(headerMetadata, &fileSourcePackageSet));
    CHK_OFAIL(mxf_uu_get_package_tracks(fileSourcePackageSet, &arrayIter));
    while (mxf_uu_next_track(headerMetadata, &arrayIter, &sourcePackageTrackSet))
    {
        CHK_OFAIL(mxf_uu_get_track_datadef(sourcePackageTrackSet, &dataDef));

        if (mxf_is_descriptive_metadata(&dataDef))
        {
            /* get to the single DMSegment */
            CHK_OFAIL(mxf_get_strongref_item(sourcePackageTrackSet, &MXF_ITEM_K(GenericTrack, Sequence), &sequenceSet));
            if (mxf_is_subclass_of(headerMetadata->dataModel, &sequenceSet->key, &MXF_SET_K(Sequence)))
            {
                CHK_OFAIL(mxf_get_array_item_count(sequenceSet, &MXF_ITEM_K(Sequence, StructuralComponents), &count));
                if (count != 1)
                {
                    /* Sequence of length 1 is expected for the DMS track */
                    continue;
                }
                
                CHK_OFAIL(mxf_get_array_item_element(sequenceSet, &MXF_ITEM_K(Sequence, StructuralComponents), 0, &arrayElement));
                CHK_OFAIL(mxf_get_strongref(headerMetadata, arrayElement, &dmSet));
            }
            else
            {
                dmSet = sequenceSet;
            }
            
            /* if it is a DMSegment with a DMFramework reference then we have the DMS track */
            if (mxf_is_subclass_of(headerMetadata->dataModel, &dmSet->key, &MXF_SET_K(DMSegment)))
            {
                if (mxf_have_item(dmSet, &MXF_ITEM_K(DMSegment, DMFramework)))
                {
                    CHK_OFAIL(mxf_get_strongref_item(dmSet, &MXF_ITEM_K(DMSegment, DMFramework), &dmFrameworkSet));
                    
                    /* if it is a APP_InfaxFramework then it is the Infax data */
                    if (mxf_is_subclass_of(headerMetadata->dataModel, &dmFrameworkSet->key, &MXF_SET_K(APP_InfaxFramework)))
                    {
                        CHK_OFAIL(get_infax_data(dmFrameworkSet, &info->ltoInfaxData));
                        break;
                    }
                }
            }
        }
    }


    /* original filename */

    CHK_OFAIL(mxf_get_strongref_item(fileSourcePackageSet, &MXF_ITEM_K(SourcePackage, Descriptor), &descriptorSet));
    if (mxf_have_item(descriptorSet, &MXF_ITEM_K(GenericDescriptor, Locators)))
    {
        CHK_OFAIL(mxf_initialise_array_item_iterator(descriptorSet, &MXF_ITEM_K(GenericDescriptor, Locators), &arrayIter));
        while (mxf_next_array_item_element(&arrayIter, &arrayElement, &arrayElementLen))
        {
            CHK_OFAIL(mxf_get_strongref(headerMetadata, arrayElement, &locatorSet));

            if (mxf_is_subclass_of(headerMetadata->dataModel, &locatorSet->key, &MXF_SET_K(NetworkLocator)))
            {
                CHK_OFAIL(mxf_uu_get_utf16string_item(locatorSet, &MXF_ITEM_K(NetworkLocator, URLString), &tempWString));
                CHK_OFAIL(wcstombs(info->filename, tempWString, sizeof(info->filename)) != (size_t)(-1));
                info->filename[sizeof(info->filename) - 1] = '\0';
                SAFE_FREE(&tempWString);
                break;
            }
        }
    }    
    
    
    /* source Infax data */
    
    CHK_OFAIL(mxf_find_set_by_key(headerMetadata, &MXF_SET_K(SourcePackage), &list));
    mxf_initialise_list_iter(&iter, list);
    while (mxf_next_list_iter_element(&iter))
    {
        sourcePackageSet = (MXFMetadataSet*)(mxf_get_iter_element(&iter));
        
        /* it is the tape SourcePackage if it has a TapeDescriptor */
        CHK_OFAIL(mxf_get_strongref_item(sourcePackageSet, &MXF_ITEM_K(SourcePackage, Descriptor), &descriptorSet));
        if (mxf_is_subclass_of(headerMetadata->dataModel, &descriptorSet->key, &MXF_SET_K(TapeDescriptor)))
        {
            /* go through the tracks and find the DMS track */
            CHK_OFAIL(mxf_uu_get_package_tracks(sourcePackageSet, &arrayIter));
            while (mxf_uu_next_track(headerMetadata, &arrayIter, &sourcePackageTrackSet))
            {
                CHK_OFAIL(mxf_uu_get_track_datadef(sourcePackageTrackSet, &dataDef));
        
                if (mxf_is_descriptive_metadata(&dataDef))
                {
                    /* get to the single DMSegment */
                    CHK_OFAIL(mxf_get_strongref_item(sourcePackageTrackSet, &MXF_ITEM_K(GenericTrack, Sequence), &sequenceSet));
                    if (mxf_is_subclass_of(headerMetadata->dataModel, &sequenceSet->key, &MXF_SET_K(Sequence)))
                    {
                        CHK_OFAIL(mxf_get_array_item_count(sequenceSet, &MXF_ITEM_K(Sequence, StructuralComponents), &count));
                        if (count != 1)
                        {
                            /* Sequence of length 1 is expected for the DMS track */
                            continue;
                        }
                        
                        CHK_OFAIL(mxf_get_array_item_element(sequenceSet, &MXF_ITEM_K(Sequence, StructuralComponents), 0, &arrayElement));
                        CHK_OFAIL(mxf_get_strongref(headerMetadata, arrayElement, &dmSet));
                    }
                    else
                    {
                        dmSet = sequenceSet;
                    }
                    
                    /* if it is a DMSegment with a DMFramework reference then we have the DMS track */
                    if (mxf_is_subclass_of(headerMetadata->dataModel, &dmSet->key, &MXF_SET_K(DMSegment)))
                    {
                        if (mxf_have_item(dmSet, &MXF_ITEM_K(DMSegment, DMFramework)))
                        {
                            CHK_OFAIL(mxf_get_strongref_item(dmSet, &MXF_ITEM_K(DMSegment, DMFramework), &dmFrameworkSet));
                            
                            /* if it is a APP_InfaxFramework then it is the Infax data */
                            if (mxf_is_subclass_of(headerMetadata->dataModel, &dmFrameworkSet->key, &MXF_SET_K(APP_InfaxFramework)))
                            {
                                CHK_OFAIL(get_infax_data(dmFrameworkSet, &info->sourceInfaxData));
                                haveSourceInfaxData = 1;
                                break;
                            }
                        }
                    }
                }
            }
                    
            break;
        }
    }
    mxf_free_list(&list);
    
    
    /* try reading Infax data from UserComments attached to the MaterialPackage if no data was found elsewhere */
    if (!haveSourceInfaxData)
    {
        CHK_OFAIL(mxf_find_singular_set_by_key(headerMetadata, &MXF_SET_K(MaterialPackage), &materialPackageSet));
        if (mxf_avid_read_string_user_comments(materialPackageSet, &nameList, &valueList))
        {
            haveSourceInfaxData = parse_infax_user_comments(nameList, valueList, &info->sourceInfaxData);

            mxf_free_list(&nameList);
            mxf_free_list(&valueList);
        }
    }

    
    return haveSourceInfaxData;
    
fail:
    SAFE_FREE(&tempWString);
    mxf_free_list(&list);
    mxf_free_list(&nameList);
    mxf_free_list(&valueList);
    return 0;    
}
예제 #28
0
int create_dv_connect(MediaSink* sink, int sinkStreamId, int sourceStreamId,
    const StreamInfo* streamInfo, int numFFMPEGThreads, int useWorkerThread, StreamConnect** connect)
{
    DVDecodeStreamConnect* newConnect;
    StreamInfo decodedStreamInfo;
    int result;

    /* register stream with sink */
    if (streamInfo->format == DV25_YUV420_FORMAT)
    {
        decodedStreamInfo = *streamInfo;
        decodedStreamInfo.format = YUV420_FORMAT;

        result = msk_accept_stream(sink, &decodedStreamInfo);
    }
    else if (streamInfo->format == DV25_YUV411_FORMAT)
    {
        decodedStreamInfo = *streamInfo;
        decodedStreamInfo.format = YUV411_FORMAT;

        result = msk_accept_stream(sink, &decodedStreamInfo);
    }
    else /* streamInfo->format == DV50_FORMAT || streamInfo->format == DV100_FORMAT */
    {
        decodedStreamInfo = *streamInfo;
        decodedStreamInfo.format = YUV422_FORMAT;

        result = msk_accept_stream(sink, &decodedStreamInfo);
    }

    /* try UYVY if default format is not accepted */
    if (!result)
    {
        decodedStreamInfo = *streamInfo;
        decodedStreamInfo.format = UYVY_FORMAT;

        result = msk_accept_stream(sink, &decodedStreamInfo);
    }

    if (!result)
    {
        /* shouldn't be here because a call to dv_connect_accept() should've returned false already */
        ml_log_error("Failed to create DV connector because format is not accepted\n");
        return 0;
    }


    if (!msk_register_stream(sink, sinkStreamId, &decodedStreamInfo))
    {
        /* could have failed if max streams exceeded for example */
        return 0;
    }


    CALLOC_ORET(newConnect, DVDecodeStreamConnect, 1);

    newConnect->useWorkerThread = useWorkerThread;
    newConnect->decodedFormat = decodedStreamInfo.format;

    if (streamInfo->format == DV25_YUV420_FORMAT || streamInfo->format == DV25_YUV411_FORMAT)
    {
        newConnect->dvDataSize = (stream_is_pal_frame_rate(streamInfo) ? 144000 : 120000);
    }
    else if (streamInfo->format == DV50_FORMAT)
    {
        newConnect->dvDataSize = (stream_is_pal_frame_rate(streamInfo) ? 288000 : 240000);
    }
    else /* streamInfo->format == DV100_FORMAT */
    {
        newConnect->dvDataSize = 576000;
    }
    if ((newConnect->dvData = (unsigned char*)calloc(
        newConnect->dvDataSize + FF_INPUT_BUFFER_PADDING_SIZE /* FFMPEG for some reason needs the extra space */,
        sizeof(unsigned char))) == NULL)
    {
        ml_log_error("Failed to allocate memory\n");
        goto fail;
    }

    newConnect->sink = sink;
    newConnect->sourceStreamId = sourceStreamId;
    newConnect->sinkStreamId = sinkStreamId;
    newConnect->streamInfo = *streamInfo;
    if (decodedStreamInfo.format == UYVY_FORMAT)
    {
        newConnect->sinkBufferSize = streamInfo->width * streamInfo->height * 2;
    }
    else if (decodedStreamInfo.format == YUV422_FORMAT)
    {
        newConnect->sinkBufferSize = streamInfo->width * streamInfo->height * 2;
    }
    else /* YUV420 / YUV411 */
    {
        newConnect->sinkBufferSize = streamInfo->width * streamInfo->height * 3 / 2;
    }

    newConnect->streamConnect.data = newConnect;
    newConnect->streamConnect.get_source_listener = ddc_get_source_listener;
    newConnect->streamConnect.sync = ddc_sync;
    newConnect->streamConnect.close = ddc_close;

    newConnect->sourceListener.data = newConnect;
    newConnect->sourceListener.accept_frame = ddc_accept_frame;
    newConnect->sourceListener.allocate_buffer = ddc_allocate_buffer;
    newConnect->sourceListener.deallocate_buffer = ddc_deallocate_buffer;
    newConnect->sourceListener.receive_frame = ddc_receive_frame;
    newConnect->sourceListener.receive_frame_const = ddc_receive_frame_const;



    /* create DV decoder */

    CHK_OFAIL(init_dv_decoder_resources());

    CHK_OFAIL(create_dv_decoder(streamInfo->format, streamInfo->width, streamInfo->height,
        numFFMPEGThreads, &newConnect->decoder));


    /* create worker thread */

    if (useWorkerThread)
    {
        CHK_OFAIL(init_mutex(&newConnect->workerMutex));
        CHK_OFAIL(init_cond_var(&newConnect->frameIsReadyCond));
        CHK_OFAIL(init_cond_var(&newConnect->workerIsBusyCond));

        CHK_OFAIL(create_joinable_thread(&newConnect->workerThreadId, worker_thread, newConnect));
    }


    *connect = &newConnect->streamConnect;
    return 1;

fail:
    ddc_close(newConnect);
    return 0;
}
예제 #29
0
int mxf_read_and_return_set(MXFFile* mxfFile, const mxfKey* key, uint64_t len,
    MXFHeaderMetadata* headerMetadata, int addToHeaderMetadata, MXFMetadataSet** set)
{
    MXFMetadataSet* newSet = NULL;
    MXFSetDef* setDef = NULL;
    uint64_t totalLen = 0;
    mxfLocalTag itemTag;
    uint16_t itemLen;
    int haveInstanceUID = 0;
    mxfKey itemKey;
    MXFItemDef* itemDef = NULL;
    MXFMetadataItem* newItem;

    assert(headerMetadata->primerPack != NULL);

    /* only read sets with known definitions */    
    if (mxf_find_set_def(headerMetadata->dataModel, key, &setDef))
    {
        CHK_ORET(create_empty_set(key, &newSet));
    
        /* read each item in the set*/
        haveInstanceUID = 0;
        do
        {
            CHK_OFAIL(mxf_read_item_tl(mxfFile, &itemTag, &itemLen));
            /* check the item tag is registered in the primer */
            if (mxf_get_item_key(headerMetadata->primerPack, itemTag, &itemKey))
            {
                /* only read items with known definition */
                if (mxf_find_item_def_in_set_def(&itemKey, setDef, &itemDef))
                {
                    CHK_OFAIL(mxf_create_item(newSet, &itemKey, itemTag, &newItem));
                    newItem->isPersistent = 1;
                    CHK_OFAIL(mxf_read_item(mxfFile, newItem, itemLen));
                    if (mxf_equals_key(&MXF_ITEM_K(InterchangeObject, InstanceUID), &itemKey))
                    {
                        mxf_get_uuid(newItem->value, &newSet->instanceUID);
                        haveInstanceUID = 1;
                    }
                }
                /* skip items with unknown definition */
                else
                {
                    CHK_OFAIL(mxf_skip(mxfFile, (int64_t)itemLen));
                }
            }
            /* skip items not registered in the primer. Log warning because the file is invalid */
            else
            {
                mxf_log_warn("Encountered item with tag %d not registered in the primer" LOG_LOC_FORMAT,
                    itemTag, LOG_LOC_PARAMS);
                CHK_OFAIL(mxf_skip(mxfFile, (int64_t)itemLen));
            }
            
            totalLen += 4 + itemLen;        
        }
        while (totalLen < len);
        
        if (totalLen != len)
        {
            mxf_log_error("Incorrect metadata set length encountered" LOG_LOC_FORMAT, LOG_LOC_PARAMS);
            goto fail;
        }
        if (!haveInstanceUID)
        {
            mxf_log_error("Metadata set does not have InstanceUID item" LOG_LOC_FORMAT, LOG_LOC_PARAMS);
            goto fail;
        }

        /* ok to add set */
        if (addToHeaderMetadata)
        {
            CHK_OFAIL(mxf_add_set(headerMetadata, newSet));
        }
    
        *set = newSet;
        return 1;
    }

    /* skip the set if the def is unknown */
    CHK_ORET(mxf_skip(mxfFile, (int64_t)len));
    *set = NULL;
    return 2;

fail:
    mxf_free_set(&newSet);
    return 0;    
}
예제 #30
0
static int archive_mxf_get_package_timecode_breaks(MXFHeaderMetadata* headerMetadata, MXFMetadataSet* packageSet,
                                                   TimecodeBreak** timecodeBreaks, long* numTimecodeBreaks)
{
    MXFArrayItemIterator arrayIter;
    MXFArrayItemIterator arrayIter2;
    uint8_t* arrayElement;
    uint32_t arrayElementLen;
    mxfUL dataDef;
    uint32_t count;
    MXFMetadataSet* packageTrackSet;
    MXFMetadataSet* sequenceSet;
    MXFMetadataSet* dmSet;
    MXFMetadataSet* dmFrameworkSet;
    MXFListIterator setsIter;
    TimecodeBreak* newTimecodeBreaks = NULL;
    long totalBreaks = 0;
    TimecodeBreak* tmp;
    

    CHK_OFAIL(mxf_uu_get_package_tracks(packageSet, &arrayIter));
    while (mxf_uu_next_track(headerMetadata, &arrayIter, &packageTrackSet))
    {
        CHK_OFAIL(mxf_uu_get_track_datadef(packageTrackSet, &dataDef));
        if (mxf_is_descriptive_metadata(&dataDef))
        {
            /* get to the sequence */
            CHK_OFAIL(mxf_get_strongref_item(packageTrackSet, &MXF_ITEM_K(GenericTrack, Sequence), &sequenceSet));
            if (mxf_is_subclass_of(headerMetadata->dataModel, &sequenceSet->key, &MXF_SET_K(Sequence)))
            {
                CHK_OFAIL(mxf_get_array_item_count(sequenceSet, &MXF_ITEM_K(Sequence, StructuralComponents), &count));
                if (count == 0)
                {
                    continue;
                }
                
                CHK_OFAIL(mxf_get_array_item_element(sequenceSet, &MXF_ITEM_K(Sequence, StructuralComponents), 0, &arrayElement));
                CHK_OFAIL(mxf_get_strongref(headerMetadata, arrayElement, &dmSet));
            }
            else
            {
                dmSet = sequenceSet;
            }
            
            /* if it is a DMSegment with a DMFramework reference then we have the DMS track */
            if (mxf_is_subclass_of(headerMetadata->dataModel, &dmSet->key, &MXF_SET_K(DMSegment)))
            {
                if (mxf_have_item(dmSet, &MXF_ITEM_K(DMSegment, DMFramework)))
                {
                    CHK_OFAIL(mxf_get_strongref_item(dmSet, &MXF_ITEM_K(DMSegment, DMFramework), &dmFrameworkSet));

                    /* check whether the DMFrameworkSet is a APP_TimecodeBreakFramework */
                    if (mxf_is_subclass_of(headerMetadata->dataModel, &dmFrameworkSet->key, &MXF_SET_K(APP_TimecodeBreakFramework)))
                    {
                        /* go back to the sequence and extract the timecode breaks */
                        
                        CHK_OFAIL(mxf_get_array_item_count(sequenceSet, &MXF_ITEM_K(Sequence, StructuralComponents), &count));
                        if (newTimecodeBreaks == NULL)
                        {
                            CHK_OFAIL((tmp = malloc(sizeof(TimecodeBreak) * (totalBreaks + count))) != NULL);
                        }
                        else
                        {
                            /* multiple tracks with timecode breaks - reallocate the array */
                            CHK_OFAIL((tmp = realloc(newTimecodeBreaks, sizeof(TimecodeBreak) * (totalBreaks + count))) != NULL);
                        }
                        newTimecodeBreaks = tmp;
                        
                        /* extract the digibeta dropouts */
                        initialise_sets_iter(headerMetadata, &setsIter);
                        mxf_initialise_array_item_iterator(sequenceSet, &MXF_ITEM_K(Sequence, StructuralComponents), &arrayIter2);
                        while (mxf_next_array_item_element(&arrayIter2, &arrayElement, &arrayElementLen))
                        {
                            TimecodeBreak* timecodeBreak = &newTimecodeBreaks[totalBreaks];
                            
                            CHK_OFAIL(mxf_get_strongref_s(headerMetadata, &setsIter, arrayElement, &dmSet));
                            CHK_OFAIL(mxf_get_position_item(dmSet, &MXF_ITEM_K(DMSegment, EventStartPosition), &timecodeBreak->position));
                            CHK_OFAIL(mxf_get_strongref_item_s(&setsIter, dmSet, &MXF_ITEM_K(DMSegment, DMFramework), &dmFrameworkSet));
                            CHK_OFAIL(mxf_get_uint16_item(dmFrameworkSet, &MXF_ITEM_K(APP_TimecodeBreakFramework, APP_TimecodeType), &timecodeBreak->timecodeType));
                            
                            totalBreaks++;
                        }
                    }
                }
            }
        }
    }
    
    *timecodeBreaks = newTimecodeBreaks;
    *numTimecodeBreaks = totalBreaks;
    return 1;

fail:
    SAFE_FREE(&newTimecodeBreaks);
    return 0;
}