AAFRESULT ImplAAFSegment::GenerateSequence(ImplAAFSequence **seq) { ImplAAFDictionary *pDictionary = NULL; ImplAAFSequence *tmp = NULL; // *** ImplAAFDataDef *datakind; XPROTECT( ) { // *** CHECK(GetDatakind(&datakind)); CHECK(GetDictionary(&pDictionary)); CHECK(pDictionary->GetBuiltinDefs()->cdSequence()-> CreateInstance ((ImplAAFObject**) &tmp)); pDictionary->ReleaseReference(); pDictionary = NULL; CHECK(tmp->AppendComponent(this)); *seq = tmp; } /* XPROTECT */ XEXCEPT { if (tmp) tmp->ReleaseReference(); tmp = 0; if(pDictionary != NULL) pDictionary->ReleaseReference(); pDictionary = 0; } XEND; return(AAFRESULT_SUCCESS); }
//**************** // AddPulldownRef() // AAFRESULT STDMETHODCALLTYPE ImplAAFSourceMob::AddPulldownRef (aafAppendOption_t /* addType !!!*/, const aafRational_t & editrate, aafSlotID_t aMobSlot, ImplAAFDataDef * pEssenceKind, aafSourceRef_t ref, aafLength_t srcRefLength, aafPulldownKind_t pulldownKind, aafPhaseFrame_t phaseFrame, aafPulldownDir_t direction) { ImplAAFSourceClip *sclp = NULL; ImplAAFTimelineMobSlot *trkd = NULL; aafPosition_t zeroPos; aafSlotID_t tmpSlotID; ImplAAFMobSlot * slot = NULL; aafBool isOneToOne; ImplAAFPulldown *pdwn = NULL; ImplAAFSequence * sequence = NULL; ImplAAFDictionary* dict = NULL; aafLength_t outLength, zero; aafInt32 patternLen; AAFRESULT status = AAFRESULT_SUCCESS; aafUInt32 mask; if (! pEssenceKind) return AAFRESULT_NULL_PARAM; XPROTECT() { GetDictionary(&dict); zero = 0; XASSERT(direction == kAAFFilmToTapeSpeed || direction == kAAFTapeToFilmSpeed, AAFRESULT_PULLDOWN_DIRECTION); zeroPos = 0; { CHECK(dict->GetBuiltinDefs()->cdPulldown()-> CreateInstance((ImplAAFObject **)&pdwn)); CHECK(pdwn->SetDataDef(pEssenceKind)); CHECK(pdwn->SetPulldownKind(pulldownKind)); CHECK(pdwn->SetPhaseFrame(phaseFrame)); CHECK(pdwn->SetPulldownDirection(direction)); CHECK(pdwn->aafPvtGetPulldownMask(pulldownKind, &mask, &patternLen, &isOneToOne)); if(isOneToOne) { CHECK(pdwn->SetLength(srcRefLength)); } else { /* Remember, this routine is given the OUTPUT length, and must determine * the input length (so the ratios look backwards) */ CHECK(pdwn->MapOffset(srcRefLength, kAAFTrue, &outLength, NULL)); CHECK(pdwn->SetLength(outLength)); } } /* If the slot exists, and there is a SCLP, extract it so that it can be appended * to the mask or pullown object later */ status = FindSlotBySlotID(aMobSlot, &slot); if (status == AAFRESULT_SUCCESS) { ImplAAFSegment *seg; CHECK(slot->GetSlotID(&tmpSlotID)); CHECK(slot->GetSegment(&seg)); sequence = dynamic_cast<ImplAAFSequence*>(seg); if(sequence != NULL) { aafLength_t foundLen; aafUInt32 numSegments; aafUInt32 n; ImplAAFComponent *subSeg; CHECK(sequence->CountComponents(&numSegments)); if(numSegments == 0) { CHECK(sequence->AppendComponent(pdwn)); CHECK(dict->GetBuiltinDefs()->cdSourceClip()-> CreateInstance((ImplAAFObject **)&sclp)); CHECK(sclp->Initialize(pEssenceKind, srcRefLength, ref)); } for(n = 0; n < numSegments; n++) { CHECK(sequence->GetNthComponent (0, &subSeg)); CHECK(subSeg->GetLength(&foundLen)); if(foundLen != zero) { CHECK(sequence->SetNthComponent(n, pdwn)); sclp = dynamic_cast<ImplAAFSourceClip*>(subSeg); break; } subSeg->ReleaseReference(); subSeg = NULL; } } else { CHECK(slot->SetSegment(pdwn)); sclp = dynamic_cast<ImplAAFSourceClip*>(seg); } XASSERT(sclp != NULL, AAFRESULT_NOT_SOURCE_CLIP); CHECK(sclp->Initialize(pEssenceKind, srcRefLength, ref)); } else { CHECK(dict->GetBuiltinDefs()->cdSourceClip()-> CreateInstance((ImplAAFObject **)&sclp)); CHECK(sclp->Initialize(pEssenceKind, srcRefLength, ref)); CHECK(AppendNewTimelineSlot(editrate, pdwn, aMobSlot, NULL, zeroPos, &trkd) ); } /* Patch the MASK into the file mob if this is a Film Editrate */ /* NOTE: This is assuming that there is a source clip on * the file mob - if it is a nested structure (i.e., SEQU), * this code is not patching the nested elements with the new * editrate and length. */ { if(pdwn != NULL) { CHECK(pdwn->SetInputSegment(sclp)); } } dict->ReleaseReference(); dict = NULL; } /* XPROTECT */ XEXCEPT { if(dict) dict->ReleaseReference(); dict = 0; } XEND; return (AAFRESULT_SUCCESS); }
//**************** // ValidateTimecodeRange() // AAFRESULT STDMETHODCALLTYPE ImplAAFSourceMob::SpecifyValidCodeRange (ImplAAFDataDef * /* pEssenceKind !!!*/, aafSlotID_t slotID, aafRational_t editrate, aafFrameOffset_t startOffset, aafFrameLength_t length64) { ImplAAFSourceClip *sclp = NULL; ImplAAFTimecode *timecodeClip = NULL; ImplAAFSequence * aSequ = NULL, *segSequ = NULL; ImplAAFFiller * filler1 = NULL, *filler2 = NULL; ImplAAFSegment * seg = NULL; ImplAAFComponent * subSegment = NULL; ImplAAFDictionary * pDict = NULL; aafPosition_t pos, zeroPos, sequPos, begPos, endPos; aafLength_t length, zeroLen, tcLen, endFillLen, firstFillLen, oldFillLen, segLen; aafLength_t tcSlotLen, sequLen; aafSourceRef_t sourceRef; ImplAAFTimelineMobSlot *newSlot, *slot; aafFrameOffset_t tcStartPos; aafTimecode_t timecode; aafUInt32 sequLoop; aafUInt32 numSegs; ImplEnumAAFComponents *sequIter = NULL; XPROTECT() { CHECK(FindTimecodeClip(startOffset, &timecodeClip, &tcStartPos, &tcSlotLen)); CHECK(timecodeClip->GetLength(&tcLen)); CHECK(timecodeClip->GetTimecode(&timecode)); if(length64 == FULL_LENGTH) { CHECK(PvtTimecodeToOffset(timecode.fps, 24, 0, 0, 0, timecode.drop, &length64)); } length = length64; zeroLen = 0; pos = startOffset; zeroPos = 0; endFillLen = tcSlotLen; endFillLen -= pos; endFillLen -= length; memset(&sourceRef, 0, sizeof(sourceRef)); CHECK(GetDictionary(&pDict)); CHECK(pDict->GetBuiltinDefs()->cdSourceClip()-> CreateInstance((ImplAAFObject **)&sclp)); if(FindSlotBySlotID(slotID, (ImplAAFMobSlot **)&slot) != AAFRESULT_SUCCESS) { CHECK(pDict->GetBuiltinDefs()->cdSequence()-> CreateInstance((ImplAAFObject **)&aSequ)); CHECK(pDict->GetBuiltinDefs()->cdFiller()-> CreateInstance((ImplAAFObject **)&filler1)); if(aSequ == NULL || filler1 == NULL) RAISE(E_FAIL); CHECK(aSequ->AppendComponent(filler1)); CHECK(aSequ->AppendComponent(sclp)); CHECK(pDict->GetBuiltinDefs()->cdFiller()-> CreateInstance((ImplAAFObject **)&filler2)); CHECK(aSequ->AppendComponent(filler2)); /* (SPR#343) Change to validate multiple ranges */ CHECK(AppendNewTimelineSlot(editrate, aSequ, slotID, NULL, zeroPos, &newSlot)); } else { CHECK(slot->GetSegment(&seg)); CHECK(seg->GenerateSequence(&segSequ)); CHECK(segSequ->GetComponents(&sequIter)); CHECK(segSequ->CountComponents(&numSegs)); for (sequLoop=0, sequPos = 0; sequLoop < numSegs; sequLoop++, sequPos += segLen) { CHECK(sequIter->NextOne(&subSegment)); CHECK(subSegment->GetLength(&segLen)); /* Skip zero-length clips, sometimes found in MC files */ if (segLen == zeroLen) continue; begPos = sequPos; endPos = sequPos + segLen; if (pos < endPos && begPos <= pos) { ImplAAFFiller *test; // Used only in test of type test = dynamic_cast<ImplAAFFiller*>(subSegment); if(test != NULL && (sequLoop == (numSegs-1))) { firstFillLen = pos; firstFillLen -= sequPos; CHECK(subSegment->GetLength(&oldFillLen)); endFillLen = oldFillLen; endFillLen -= length; endFillLen -= firstFillLen; /****/ CHECK(subSegment->SetLength(firstFillLen)); /* 1.x does not have a Sequence Length property */ CHECK(segSequ->GetLength(&sequLen)); sequLen -= oldFillLen; sequLen += firstFillLen; CHECK(segSequ->SetLength(sequLen)); CHECK(pDict->GetBuiltinDefs()->cdFiller()-> CreateInstance((ImplAAFObject **)&filler2)); //!!! filler2 = CreateImpl(CLSID_AAFFiller(_file, mediaKind, endFillLen); CHECK(segSequ->AppendComponent(sclp)); CHECK(segSequ->AppendComponent(filler2)); break; } else RAISE(AAFRESULT_NOT_IN_CURRENT_VERSION); } } /* for */ sequIter->ReleaseReference(); sequIter = NULL; //!!! /* Release reference, so the useCount is decremented */ // if (subSegment) // { // subSegment->ReleaseObject(); // subSegment = NULL; // } } if(aSequ!= NULL) { aSequ->ReleaseReference(); aSequ = NULL; } if(segSequ!= NULL) { segSequ->ReleaseReference(); segSequ = NULL; } if(filler1!= NULL) { filler1->ReleaseReference(); filler1 = NULL; } if(filler2!= NULL) { filler2->ReleaseReference(); filler2 = NULL; } if(seg!= NULL) { seg->ReleaseReference(); seg = NULL; } if(subSegment!= NULL) { subSegment->ReleaseReference(); subSegment = NULL; } if(pDict!= NULL) { pDict->ReleaseReference(); pDict = NULL; } if(sclp!= NULL) { sclp->ReleaseReference(); sclp = NULL; } if(timecodeClip!= NULL) { timecodeClip->ReleaseReference(); timecodeClip = NULL; } } XEXCEPT { if(aSequ!= NULL) aSequ->ReleaseReference(); aSequ = 0; if(segSequ!= NULL) segSequ->ReleaseReference(); segSequ = 0; if(filler1!= NULL) filler1->ReleaseReference(); filler1 = 0; if(filler2!= NULL) filler2->ReleaseReference(); filler2 = 0; if(seg!= NULL) seg->ReleaseReference(); seg = 0; if(subSegment!= NULL) subSegment->ReleaseReference(); subSegment = 0; if(pDict!= NULL) pDict->ReleaseReference(); pDict = 0; if(sclp!= NULL) sclp->ReleaseReference(); sclp = 0; if(timecodeClip!= NULL) timecodeClip->ReleaseReference(); timecodeClip = 0; } XEND; return (AAFRESULT_SUCCESS); }
// Override from AAFMobSlot AAFRESULT STDMETHODCALLTYPE ImplAAFEventMobSlot::SetSegment (/*[in]*/ ImplAAFSegment * pSegment) { ImplAAFSequence *pSequence = NULL; ImplAAFEvent *pEvent = NULL; ImplAAFComponent *pComponent = NULL; ImplAAFDictionary *pDict = NULL; ImplAAFDataDefSP pComponentDataDef; aafBool willConvert; if (NULL == pSegment) return AAFRESULT_NULL_PARAM; // Do even attempt to set the given segment if has already been // attached to another persistent object. if (pSegment->attached()) return AAFRESULT_OBJECT_ALREADY_ATTACHED; XPROTECT() { // Validate the following constraints if the segment is a sequence: // A) all events must have the same Event subclass and // B) all events must have the same data kind. // C) datakind of the each event must be the same as the sequence. // D) the positions must be increasing. // // Otherwise the segment must be an event. // pSequence = dynamic_cast<ImplAAFSequence *>(pSegment); if (NULL != pSequence) { aafUInt32 i; aafUInt32 numberOfComponents = 0; aafPosition_t previousPosition; // Save the sequences data definition guid. ImplAAFDataDefSP pSequDataDef; CHECK(pSequence->GetDataDef(&pSequDataDef)); // There must be at least one component in the sequence. CHECK(pSequence->CountComponents(&numberOfComponents)); if (0 >= numberOfComponents) RAISE(AAFRESULT_OBJECT_SEMANTIC); // Get the first component so that we can extract information // to compare to any remaining elements. CHECK(pSequence->GetNthComponent(0, &pComponent)); // The component must have the same data definition [id] as the sequence. CHECK(pComponent->GetDataDef(&pComponentDataDef)); CHECK(pComponentDataDef->DoesDataDefConvertTo(pSequDataDef, &willConvert)); if (willConvert == kAAFFalse) RAISE(AAFRESULT_OBJECT_SEMANTIC); // Get the runtime type info for validation. aafUID_t firstComponentType; CHECK(pComponent->GetObjectClass(&firstComponentType)); // The component MUST be an event. pEvent = dynamic_cast<ImplAAFEvent *>(pComponent); if (NULL == pEvent) RAISE(AAFRESULT_OBJECT_SEMANTIC); // Save the position of the first event so that we can use this // as our starting value... CHECK(pEvent->GetPosition(&previousPosition)); // Release reference before reusing variable. pComponent->ReleaseReference(); pComponent = NULL; // Make sure that all components in the sequence have the same // data definition and represent the same event class. for (i = 1; i < numberOfComponents; ++i) { CHECK(pSequence->GetNthComponent(i, &pComponent)); // The component must have the same data definition [id] as the // sequence. CHECK(pComponentDataDef->DoesDataDefConvertTo(pSequDataDef, &willConvert)); if (willConvert == kAAFFalse) RAISE(AAFRESULT_INVALID_DATADEF); // Validate that this event is the "same" type of event as the // first component of the sequence. aafUID_t componentType; CHECK(pComponent->GetObjectClass(&componentType)); if (0 != memcmp(&firstComponentType, &componentType, sizeof(firstComponentType))) RAISE(AAFRESULT_OBJECT_SEMANTIC); // The component MUST be an event. pEvent = dynamic_cast<ImplAAFEvent *>(pComponent); if (NULL == pEvent) RAISE(AAFRESULT_OBJECT_SEMANTIC); // Make sure the position of this event is no earlier then the // previous event. aafPosition_t currentPosition; CHECK(pEvent->GetPosition(¤tPosition)); if (currentPosition < previousPosition) RAISE(AAFRESULT_OBJECT_SEMANTIC); // Save the current position to compare to the next event. previousPosition = currentPosition; pComponent->ReleaseReference(); pComponent = NULL; } } else { // The segment must be an event. pEvent = dynamic_cast<ImplAAFEvent *>(pSegment); if (NULL == pEvent) RAISE(AAFRESULT_OBJECT_SEMANTIC); } // Call the parent class to set the segment... CHECK(ImplAAFMobSlot::SetSegment(pSegment)); } XEXCEPT { if (NULL != pComponent) pComponent->ReleaseReference(); pComponent = 0; if (NULL != pDict) pDict->ReleaseReference(); pDict = 0; } XEND; return(AAFRESULT_SUCCESS); }