博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Adobe Premiere Pro导入插件开发遇到的一个问题
阅读量:5097 次
发布时间:2019-06-13

本文共 3735 字,大约阅读时间需要 12 分钟。

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

static prMALErrorSDKGetPrefs8(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()函数的。

staticprMALErrorSDKGetSourceVideo(imStdParms *stdparms,imFileRef    fileRef,imSourceVideoRec *sourceVideoRec){    int ret;    ImporterLocalRec8H ldataH = reinterpret_cast
(sourceVideoRec->inPrivateData); ImporterLocalRec8Ptr localRecP = reinterpret_cast
(*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
(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的这个机制还是有道理的。如果用户私有数据没有更改,很大可能是不需要重新渲染画面的。这在某些计算频繁的场景下可能能够提供一定的性能提升。但是在文档里面并没有注明这一点。所以实际上,这个现象看起来像是一个锅实际上并不是一个锅……

转载于:https://www.cnblogs.com/csuftzzk/p/adobe_premiere_pro_importer.html

你可能感兴趣的文章
Kotlin动态图
查看>>
从零开始系列之vue全家桶(1)安装前期准备nodejs+cnpm+webpack+vue-cli+vue-router
查看>>
Jsp抓取页面内容
查看>>
大三上学期软件工程作业之点餐系统(网页版)的一些心得
查看>>
可选参数的函数还可以这样设计!
查看>>
[你必须知道的.NET]第二十一回:认识全面的null
查看>>
Java语言概述
查看>>
关于BOM知识的整理
查看>>
Android设计模式源码解析之外观模式(Facade)
查看>>
使用word发布博客
查看>>
面向对象的小demo
查看>>
微服务之初了解(一)
查看>>
GDOI DAY1游记
查看>>
收集WebDriver的执行命令和参数信息
查看>>
数据结构与算法(三)-线性表之静态链表
查看>>
mac下的mysql报错:ERROR 1045(28000)和ERROR 2002 (HY000)的解决办法
查看>>
Hmailserver搭建邮件服务器
查看>>
django之多表查询-2
查看>>
快速幂
查看>>
改善C#公共程序类库质量的10种方法
查看>>