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; }
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; }