Пример #1
0
static int cps_seek_timecode(void* data, const Timecode* timecode, TimecodeType type, TimecodeSubType subType)
{
    ClipSource* clipSource = (ClipSource*)data;
    int64_t originalPosition = -1;
    int64_t position;

    /* get position so we can recover is seek is outside the clip boundaries */
    if (!msc_get_position(clipSource->targetSource, &originalPosition))
    {
        originalPosition = -1; /* unknown */
    }


    int result = msc_seek_timecode(clipSource->targetSource, timecode, type, subType);
    if (originalPosition < 0 || result != 0)
    {
        return result;
    }

    /* check the seek is within the clip boundaries */

    if (!msc_get_position(clipSource->targetSource, &position))
    {
        /* TODO: what now? */
        /* assume outside - go back to original position */
        msc_seek(clipSource->targetSource, originalPosition);

        return -1;
    }

    if (clipSource->duration >= 0)
    {
        if (position < clipSource->start ||
            position > clipSource->start + clipSource->duration)
        {
            /* outside - go back to original position */
            msc_seek(clipSource->targetSource, originalPosition);

            return -1;
        }
    }
    else if (clipSource->start > 0)
    {
        if (position < clipSource->start)
        {
            /* outside - go back to original position */
            msc_seek(clipSource->targetSource, originalPosition);

            return -1;
        }
    }

    return result;
}
Пример #2
0
static int mls_seek(void* data, int64_t position)
{
    MultipleMediaSources* multSource = (MultipleMediaSources*)data;
    MediaSourceElement* ele = &multSource->sources;
    int seekResult = 0;
    int syncResult;

    /* make sure the sources are in sync */
    if ((syncResult = sync_sources(multSource)) != 0)
    {
        return syncResult;
    }

    while (ele != NULL && ele->source != NULL)
    {
        if (!SOURCE_IS_DISABLED(ele))
        {
            seekResult = msc_seek(ele->source, position);
            if (seekResult != 0 )
            {
                break;
            }
        }

        ele = ele->next;
    }

    if (seekResult == 0)
    {
        /* update sync position */
        multSource->syncPosition = position;
    }

    return seekResult;
}
Пример #3
0
static int sync_sources(MultipleMediaSources* multSource)
{
    MediaSourceElement* ele = &multSource->sources;
    int64_t position;
    int syncResult = 0;

    while (ele != NULL && ele->source != NULL)
    {
        if (!SOURCE_IS_DISABLED(ele))
        {
            if (!msc_get_position(ele->source, &position))
            {
                syncResult = -1;
                break;
            }

            if (position != multSource->syncPosition)
            {
                /* seek back to the sync position */
                syncResult = msc_seek(ele->source, multSource->syncPosition);
                if (syncResult != 0)
                {
                    break;
                }
            }
        }

        ele = ele->next;
    }

    return syncResult;
}
Пример #4
0
static int cps_seek(void* data, int64_t position)
{
    ClipSource* clipSource = (ClipSource*)data;

    if (clipSource->duration >= 0)
    {
        /* check the position is within the clip boundaries */
        if (position > clipSource->duration)
        {
            return 0;
        }

        return msc_seek(clipSource->targetSource, clipSource->start + position);
    }
    else if (clipSource->start > 0)
    {
        return msc_seek(clipSource->targetSource, clipSource->start + position);
    }

    return msc_seek(clipSource->targetSource, position);
}
Пример #5
0
int cps_create(MediaSource* targetSource, const Rational* frameRate, int64_t start, int64_t duration, ClipSource** clipSource)
{
    ClipSource* newClipSource;

    if (start > 0 && !msc_seek(targetSource, start))
    {
        ml_log_warn("Failed to seek to start of the clip\n");
    }

    CALLOC_ORET(newClipSource, ClipSource, 1);

    newClipSource->targetSource = targetSource;
    newClipSource->start = (start < 0) ? 0 : start;
    newClipSource->duration = duration;
    newClipSource->frameRate = *frameRate; /* note: frameRate could be 0/0 */

    newClipSource->mediaSource.data = newClipSource;
    newClipSource->mediaSource.is_complete = cps_is_complete;
    newClipSource->mediaSource.post_complete = cps_post_complete;
    newClipSource->mediaSource.finalise_blank_source = cps_finalise_blank_source;
    newClipSource->mediaSource.get_num_streams = cps_get_num_streams;
    newClipSource->mediaSource.get_stream_info = cps_get_stream_info;
    newClipSource->mediaSource.set_frame_rate_or_disable = cps_set_frame_rate_or_disable;
    newClipSource->mediaSource.disable_stream = cps_disable_stream;
    newClipSource->mediaSource.disable_audio = cps_disable_audio;
    newClipSource->mediaSource.disable_video = cps_disable_video;
    newClipSource->mediaSource.stream_is_disabled = cps_stream_is_disabled;
    newClipSource->mediaSource.read_frame = cps_read_frame;
    newClipSource->mediaSource.is_seekable = cps_is_seekable;
    newClipSource->mediaSource.seek = cps_seek;
    newClipSource->mediaSource.seek_timecode = cps_seek_timecode;
    newClipSource->mediaSource.get_length = cps_get_length;
    newClipSource->mediaSource.get_position = cps_get_position;
    newClipSource->mediaSource.get_available_length = cps_get_available_length;
    newClipSource->mediaSource.eof = cps_eof;
    newClipSource->mediaSource.set_source_name = cps_set_source_name;
    newClipSource->mediaSource.set_clip_id = cps_set_clip_id;
    newClipSource->mediaSource.close = cps_close;
    newClipSource->mediaSource.get_buffer_state = cps_get_buffer_state;
    newClipSource->mediaSource.convert_position = cps_convert_position;

    *clipSource = newClipSource;
    return 1;
}
Пример #6
0
static int mls_seek_timecode(void* data, const Timecode* timecode, TimecodeType type, TimecodeSubType subType)
{
    MultipleMediaSources* multSource = (MultipleMediaSources*)data;
    MediaSourceElement* ele = &multSource->sources;
    int seekResult = 0;
    int haveATimedOutResult = 0;
    int failed = 0;
    MediaSourceElement* passedEle = NULL;
    int64_t position;
    int syncResult;

    /* make sure the sources are in sync */
    if ((syncResult = sync_sources(multSource)) != 0)
    {
        return syncResult;
    }

    /* find the source that supports and successfully seeks to the timecode */
    while (ele != NULL && ele->source != NULL)
    {
        if (!SOURCE_IS_DISABLED(ele))
        {
            seekResult = msc_seek_timecode(ele->source, timecode, type, subType);
            if (seekResult == 0)
            {
                passedEle = ele;
                if (!msc_get_position(ele->source, &position))
                {
                    ml_log_error("Failed to get position at seek to timecode\n");
                    return -1;
                }
                break;
            }
            else if (seekResult == -2)
            {
                haveATimedOutResult = 1;
            }
        }

        ele = ele->next;
    }
    if (passedEle == NULL)
    {
        /* none of the sources could be seeked to the timecode */
        if (haveATimedOutResult)
        {
            /* assume that the timed out source could have seeked to the timecode */
            return -2;
        }
        return -1;
    }

    /* try seek to the position corresponding to the timecode for the sources that failed */
    ele = &multSource->sources;
    while (ele != NULL && ele->source != NULL)
    {
        if (!SOURCE_IS_DISABLED(ele))
        {
            if (ele != passedEle && msc_seek(ele->source, position) != 0)
            {
                failed = 1;
                break;
            }
        }

        ele = ele->next;
    }

    if (!failed)
    {
        /* update sync position */
        multSource->syncPosition = position;
    }

    return !failed ? 0 : -1;
}