zoukankan      html  css  js  c++  java
  • Adobe Premiere Pro导入插件开发遇到的一个问题

          最近在更新公司一款Premiere Pro CC导入插件的时候,遇到了一个神奇的现象。具体的现象是这样的:我们的插件需要将一些私有的文件数据放到插件中,比如说当前活动的文件名。当插件中收到不同的selector时,我们能够随时获取到这些私有数据进行操作。具体来说,我们是在收到imGetPrefs8这个selector时,进行设置的。回调函数代码如下:

    static prMALError
    SDKGetPrefs8(
    imStdParms			*stdParms,
    imFileAccessRec8	*fileInfo8,
    imGetPrefsRec		*prefsRec)
    {
    	//-----------------
    	// The first time you are called (or if you've been Quieted or Closed)
    	// you will get asked for prefs data.  First time called, return the
    	// size of the buffer you want Premiere to store prefs for your plug-in.
    
    	// Note: if canOpen is not set to kPrTrue, I'm not getting this selector. Why?
    	// Answer: because this selector is associated directly with "hasSetup"
    
    	if (prefsRec->prefsLength == 0) {
    		prefsRec->prefsLength = sizeof(MediaSettings);
    	}
    	else {
    		MediaSettings* settings = (MediaSettings*)prefsRec->prefs;
    		//do not show dialog for the first time.
    		if (fileInfo8->fileref != imInvalidHandleValue) {
    			auto ctx = (FileContext*)(fileInfo8->fileref);
    			if (!ctx || !ctx->media_source) {
    				return malNoError;
    			}  
    			auto oldSettings = ctx->media_source->GetMediaSettings(); 
    			settings->layout = oldSettings.layout;
    			settings->lock_direction = oldSettings.lock_direction;
    			settings->use_flowstate = oldSettings.use_flowstate;
    			settings->media_case = oldSettings.media_case;
    			settings->need_update = !settings->need_update;
    			std::string currentFile = ctx->media_source->GetFilePath();
                ctx->media_source->ShowSettingsDialog(settings, currentFile);
    			updateSettingFromFile(settings);
    			ctx->media_source->UpdateSettings(settings);
    		} 
    		else {
    			//init settings
    			settings->use_flowstate = true;
    		} 
    	}
    	return malNoError;
    }
    

      根据Adobe官方提供的文档说明,imGetPrefs8这个selector在文件导入的时候会连续发送两次。第一次调用回调函数是为了获取用户私有数据缓存区的大小,Host程序会给我们分配这么大的一块缓冲区。第二次调用的时候,这块缓冲区已经分配好了。我们只要往这块内存写入私有用户数据就行了。按道理说,这个过程非常清晰明了,不应该出现什么问题。可是在我实际调试的时候,弹窗获取到用户输入后,并没有马上生效!那么,我是怎么判断用户输入之后没有生效呢?一般来说,如果用户更改了什么设置,那么需要插件立即去调用SDKGetSourceVideo()函数的。

    static
    prMALError
    SDKGetSourceVideo(
    imStdParms *stdparms,
    imFileRef    fileRef,
    imSourceVideoRec *sourceVideoRec)
    {
        int ret;
    
        ImporterLocalRec8H ldataH = reinterpret_cast<ImporterLocalRec8H>(sourceVideoRec->inPrivateData);
        ImporterLocalRec8Ptr localRecP = reinterpret_cast<ImporterLocalRec8Ptr>(*ldataH);
    
        // Get parameters for ReadFrameToBuffer()
        imFrameFormat* frameFormat = &sourceVideoRec->inFrameFormats[0];
        prRect theRect;
        if (frameFormat->inFrameWidth == 0 && frameFormat->inFrameHeight == 0)
        {
            frameFormat->inFrameWidth = localRecP->theFile.width;
            frameFormat->inFrameHeight = localRecP->theFile.height;
        }
        // Windows and MacOS have different definitions of Rects, so use the cross-platform prSetRect
        prSetRect(&theRect, 0, 0, frameFormat->inFrameWidth, frameFormat->inFrameHeight);
        localRecP->PPixCreatorSuite->CreatePPix(sourceVideoRec->outFrame, PrPPixBufferAccess_ReadWrite, frameFormat->inPixelFormat, &theRect);
        csSDK_int32 theFrame = static_cast<csSDK_int32>(sourceVideoRec->inFrameTime / (*ldataH)->theFile.frameRate);
        FileContext* ctx = (FileContext*)(localRecP)->fileRef;
        if (ctx == nullptr) {
            return imNoContent;
        }
        
        ...
        ...
        
    
        return imNoErr;
    }

           这个函数负责根据当用的用户设置来重新生成一帧数据传递给Host程序渲染,这样用户才能实时看到设置生效了。问题是,我们的用户输入改变之后,SDKGetSourceVideo()这个方法并没有再次调用!那是什么原因导致的呢?难道是Premiere主程序有什么Bug?经过不断调试才发现,这个锅Premiere不能背啊!原因是,我在imGetPrefs8的回调函数中并没有修改私有数据。也就是说,在上面的SDKGetPrefs8()方法中,我通过prefsRec获取到用户私有数据缓冲区之后,如果没有修改过这块内存区的数据的话,Premiere会认为不需要重新渲染画面,也就不会再次调用SDKGetSourceVideo()方法了。

    MediaSettings* settings = (MediaSettings*)prefsRec->prefs;

          这么看来,Premiere的这个机制还是有道理的。如果用户私有数据没有更改,很大可能是不需要重新渲染画面的。这在某些计算频繁的场景下可能能够提供一定的性能提升。但是在文档里面并没有注明这一点。所以实际上,这个现象看起来像是一个锅实际上并不是一个锅……

  • 相关阅读:
    CCF CSP 题解
    CCF CSP 2019032 二十四点
    CCF CSP 2018121 小明上学
    CCF CSP 2019092 小明种苹果(续)
    CCF CSP 2019091 小明种苹果
    CCF CSP 2019121 报数
    CCF CSP 2019031 小中大
    CCF CSP 2020061 线性分类器
    CCF CSP 2020062 稀疏向量
    利用国家气象局的webservice查询天气预报(转载)
  • 原文地址:https://www.cnblogs.com/csuftzzk/p/adobe_premiere_pro_importer.html
Copyright © 2011-2022 走看看