输入

本文详细解析了一个音视频播放器从设置播放数据源到最终读取文件的过程,包括初始化播放器、处理数据源命令、识别文件格式等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 函数PVPlayer::prepareAsync():

1)判断是否已经设置数据源,

2)如果没有设置,将命令设置播放数据源(PlayerSetDataSource)加入到命令队列中,

3)如果已经设置数据源,则将命令PlayerPrepare加入到命令队列中;

4)返回。

2 函数PlayerSetDataSource(mDataSourcePath,run_init,this)

参数:mDataSourcePath是要播放文件的路径地址(如:/sdcard/video/lvxing.mp3),

run_init:命令在异步模式下执行,作为回调函数;

this:PVPlayer。

3 函数PlayerDriver::handleSetDataSource

对添加数据源命令进行处理,

1)判断是否已经设置过数据源,如果有则将参数mDataSource删除;

2)构造一个PVPlayerDataSourceURL,用mDataSource保存,这个类是继承类PVPlayerDataSource的;

类PVPlayerDataSourceURL,是类PVPlayerDataSource的子类,用于保存数据源;包含许多成员函数对主要是对数据源进行操作;

成员量:

类OneClip

uint32 iCurrentClip:当前源文件序号,主要用于生成播放列表;

Oscl_Vector iClipList:vector量,播放列表,保存源文件;

3)oscl_UTF8ToUnicode将文件的绝对路径转化为Unicode;

4)mDataSource->SetDataSourceURL(wFileName),wFileName包含转化后的Unicode,将wFileName传递给iClipList中保存;

5)判断数据流类型,分为三种情况:rtsp(实时流传输协议流),http(超文本传输协议流),绝对路径;在此是绝对路径文件。

6)mDataSource->SetDataSourceFormatType,设置源文件格式,目前还是PVMF_MIME_FORMAT_UNKNOWN,未知格式;

7)通过url判断文件格式是否是.sdp,如果格式是sdp格式,则不用识别这一个过程,直接将文件格式设置为PVMF_MIME_DATA_SOURCE_SDP_FILE;

8)新建类PVMFSourceContextData用mLocalContextData保存,并调用mDataSource->SetDataSourceContextData关联到mDataSource,将mLocalContextData保存在iClipList[iCurrentClip].iContext;

类PVMFSourceContextData是类PVInterface的子类;

接着调用此类的成员函数:EnableCommonSourceContext(),将类的成员iCommonDataContextValid设置为true,在后面会有所体现;

9)调用mPlayer->AddDataSource(*mDataSource, command),进入到下一层添加数据源,在此mPlayer实际是指向PVPlayerEngine的,在此函数中将mDataSource加入到vector量paramvec中,并将command加入到命令队列,接下来在Run中处理。

此处的command是new PlayerSetDataSource(mDataSourcePath,run_init,this),其中的this是PVPlayer;

paramvec是一个vector量,先分配一个空间,在用param(类型是union PVPlayerEngineCommandParamUnion),保存mDataSource,再将param插入到vector中;

PVPlayerEngineCommand cmd(aCmdType, commandId, aContextData, aParamVector, aAPICommand);

参数:

aCmdType:命令的类型;

commandId:命令的ID;

aContextData:command;

aParamVector:包含mDataSource的vector量;

到目前为止,有关数据源的仍然是mDataSource,而且仅是涉及到源文件的存放路径而已,还没有真正的数据流产生。

4 函数PVPlayerEngine::Run()

此函数是引擎层对命令的处理函数:

iCurrentCmd:是vector类型,大小为1,保存当前正被处理的命令;

iCmdToCancel:大小为1,保存当前正被取消的命令;

iPendingCmds:保存已经被请求的命令,也就是就要处理的命令;

1)首先检查Engine状态,确定不是在PVP_ENGINE_STATE_RESETTING;

2)检查在iPendingCmds中的命令是不是错误处理请求,

3)检查iCurrentCmd当前正在处理的命令,并做相应的操作以完成命令;

4)检查iPendingCmds是否有取消命令的请求;

5)检查参数iRollOverState,做相应操作(?);

6)进入常规命令处理流程,将iPendingCmds中顶层命令取出,在顶部插入到iCurrentCmd中,根据命令的类型做相应处理;

7)调用函数PVPlayerEngine::DoAddDataSource(&cmd);

5 函数PVPlayerEngine::DoAddDataSource(PVPlayerEngineCommand& aCmd);

参数就是上面的cmd;

1)获取mDataSource,不过将其类型转化为PVPlayerDataSource*,保存为iDataSource;

2)调用iDataSource->GetDataSourceContextData(),获取前面构造的mLocalContextData(PVMFSourceContextData*),并将其转化为PVInterface*类型保存于pvInterface中;类PVMFSourceContextData继承于类PVInterface

3)调用pvInterface->queryInterface(localDataSrcUuid, localDataSrc),获取对用UUID的接口指针,queryInterface为虚函数,实际调用其子类PVMFLocalDataSource中的对应函数,返回指向PVMFLocalDataSource的指针,保存于localDataSrc中,做类型转化,回复原来类型,保存于opaqueData中;

也就是构造了类PVMFLocalDataSource,类PVMFLocalDataSource也继承类PVInterface;

类PVMFLocalDataSource保存本地回放的源数据,

4)检查文件格式如果是未知格式(PVMF_MIME_FORMAT_UNKNOWN),调用DoQuerySourceFormatType识别文件格式,处于异步处理模式,先返回,将命令加入对列等待处理;

查询文件格式的函数原型:DoQuerySourceFormatType(aCmd.GetCmdId(), aCmd.GetContext()),此函数的参数是命令ID和类PVPlayerEngineCommand中的成员量iContextData;

5)函数DoAddDataSource退出,返回到Run()中。

6 PVPlayerEngine::DoQuerySourceFormatType(PVCommandId aCmdId, OsclAny* aCmdContext)

参数:命令ID,aContextData:指向PlayerSetDataSource;

context(PVPlayerEngineContext*)保存命令ID和aCmdContext,aCmdContext指向PlayerSetDataSource,包含源文件的绝对路径

1)iDataSource->GetDataSourceContextData()获取mLocalContextData(PVMFSourceContextData*),用opaqueData保存,并将其类型转化为PVInterface,保存于pvInterface;

2)调用pvInterface->queryInterface(SourceContextDataUuid, SourceContextData),实际调用的是类PVMFSourceContextData的成员函数queryInterface,此函数返回一个指向类PVMFSourceContextData的指针,保存于SourceContextData中,就是前面的mLocalContextData;

3)调用SourceContextData->CommonData()获得aSourceContextDataCommon(PVMFSourceContextDataCommon*);

在类PVMFSourceContextDataCommon中有个成员PVMFCPMPluginAccessInterfaceFactory* iRecognizerDataStreamFactory,保存到DataStreamDataFactory

4)iPlayerRecognizerRegistry.QueryFormatType(DataStreamDataFactory, *this, (OsclAny*) context),识别文件格式;

PVPlayerRecognizerRegistry iPlayerRecognizerRegistry,是Engine的识别器的注册类;

5)根据上面函数的执行结果返回。

当目前还没有涉及到文件数据的传递,仅是源文件存储路径的传递;

7 函数PVPlayerRecognizerRegistry::QueryFormatType(PVMFCPMPluginAccessInterfaceFactory* aDataStreamFactory, PVPlayerRecognizerRegistryObserver& aObserver, OsclAny* aCmdContext)

参数:

PVPlayerRecognizerRegistryObserver:this,指向PVPlayerEngine,作为事件的观察者;

OsclAny* aCmdContext,指向类PlayerSetDataSource,包含文件路径;

1)准备工作:略;

2)调用函数PVMFRecognizerRegistry::OpenSession(iRecSessionId, *this),this指向PVPlayerRecognizerRegistry;开启与识别器的会话(?)

3)调用函数

PVMFRecognizerRegistry::Recognize(iRecSessionId, *iDataStreamFactory, NULL, iRecognizerResult, NULL);

其中iRecSessionId是类PVMFRecognizerRegistry的成员,在类构造时会对其设定初值;iRecognizerResult是一个vector量,保存识别的结果;

iDataStreamFactory就是前面指向类PVMFCPMPluginAccessInterfaceFactory的指针。

4)函数结束。

到现在已经没有参数涉及到要播放的源文件的路径了,那后面是怎么读取这个文件的呢???

8 函数PVMFRecognizerRegistry::OpenSession(PVMFSessionId& aSessionId, PVMFRecognizerCommmandHandler& aCmdHandler)

参数:

aSessionId:类型是int32;

aCmdHandler指向类PVMFRecognizerCommmandHandler,是类PVPlayerRecognizerRegistry的父类之一,所以PVPlayerRecognizerRegistry也是此函数的观察者;

1)首先获得指向类PVMFRecognizerRegistryImpl的指针pvrecregimpl,这是一个实现类;

2)调用函数pvrecregimpl->OpenSession(aSessionId, aCmdHandler),此函数的作用就是将这个Session加入到Sessionlist中,并将aSessionId输出;

9 函数

PVMFRecognizerRegistry::Recognize(PVMFSessionId aSessionId, PVMFDataStreamFactory& aSourceDataStreamFactory, PVMFRecognizerMIMEStringList* aFormatHint,
        Oscl_Vector& aRecognizerResult, OsclAny* aCmdContext, uint32 aTimeout)

同样是调用对应实现类中的相应函数pvrecregimpl->Recognize(aSessionId, aSourceDataStreamFactory, aFormatHint, aRecognizerResult, aCmdContext, aTimeout),此函数将命令加入到命令队列中处理。

现在函数传递的所有参数中没有涉及到源文件的任何信息!!

10 函数PVMFRecognizerRegistryImpl::Run()

对上面的识别命令进行处理。

根据命令类型,调用函数PVMFRecognizerRegistryImpl::DoRecognize()

1)从当前命令列表中读出某些参数,如返回结果recresult,iDataStreamFactory;

2)调用函数PVMFRecognizerRegistryImpl::CreateDataStream()创建iDataStream,是指向类PVMIDataStreamSyncInterface的指针,函数返回不成功,则退出识别函数,进行错误处理;

3)使用布尔量oRunRecognition进入while循环,直到能真正识别文件格式才退出;

 

11 函数PVMFRecognizerRegistryImpl::CreateDataStream()

用于创建数据流指针iDataStream,iDataStream指向类PVMIDataStreamSyncInterface,此类继承类PVInterface,这时就会用到iDataStreamFactory了

1)调用iDataStreamFactory->CreatePVMFCPMPluginAccessInterface(uuid),参数uuid是PVMIDataStreamSyncInterfaceUuid,函数返回一个指向类PVInterface的指针intf,再将此指针转化为PVMIDataStreamSyncInterface*类型,此函数是个虚函数。

类PVMIDataStreamSyncInterfaceRefFactory继承于类PVMFDataStreamFactory也就是类PVMFCPMPluginAccessInterfaceFactory,又继承类PVInterface,所以此函数实际调用的是类PVMIDataStreamSyncInterfaceRefFactory的成员函数。

此函数有调用PVMIDataStreamSyncInterfaceRefImpl::CreateDataStreamSyncInterfaceRefImpl(iFileName)来创建,这时涉及到一个参数iFileName,其声明如下:OSCL_wHeapString iFileName,与前面保存Unicode的变量wFileName声明一致,两者应该是共用内存空间

2)调用函数iDataStream->OpenSession(iDataStreamSessionID, PVDS_READ_ONLY),实际调用函数PVMIDataStreamSyncInterfaceRefImpl::OpenSession

此函数会打开要播放的文件,涉及到数据流的传输,iDataStream保存数据流,

3)打开文件成功与否,函数返回标志状态。

12 函数PVMIDataStreamSyncInterfaceRefImpl::OpenSession(PvmiDataStreamSession& aSessionID,
        PvmiDataStreamMode aMode,
        bool nonblocking)

参数:aSessionID:ID号,作为输出参数;aMode,指明文件的读写模式,输入参数;

在对文件操作时可以通过参数iFileHandle(OsclFileHandle*),也可以通过iFileName,在此是通过后者。

1)新建iFileObject(Oscl_File *);

2)调用函数iFileObject->Open(iFileName.get_cstr(), Oscl_File::MODE_READ, iFs),打开文件,文件打开成功返回0,;

3)

13 函数Oscl_File::Open(const char *filename, uint32 mode, Oscl_FileServer& fileserv)

调用函数CallNativeOpen(filename, mode , params, fileserv)完成操作

多次打开文件,用iDataStream(PVMIDataStreamSyncInterface*)保存数据流,识别文件格式后要关闭会话,将包含数据流的量删除。在识别文件格式后会调用回调函数通知识别格式命令已经完成,用相应参数保存文件格式,

回调函数:

PVPlayerRecognizerRegistry::RecognizerCommandCompleted,在此函数的最后调用函数RunIfNotReady(),通知调度器,运行当前AO,也就是在接下来调用函数PVPlayerRecognizerRegistry::Run(),这个Run函数再去调用iObserver->RecognizeCompleted,此处的观察者就是Engine,接着又调用函数PVPlayerEngine::DoSetupSourceNode;

完成文件格式识别后,要建立源节点

资源下载链接为: https://pan.quark.cn/s/22ca96b7bd39 在 IT 领域,文档格式转换是常见需求,尤其在处理多种文件类型时。本文将聚焦于利用 Java 技术栈,尤其是 Apache POI 和 iTextPDF 库,实现 doc、xls(涵盖 Excel 2003 及 Excel 2007+)以及 txt、图片等格式文件向 PDF 的转换,并实现在线浏览功能。 先从 Apache POI 说起,它是一个强大的 Java 库,专注于处理 Microsoft Office 格式文件,比如 doc 和 xls。Apache POI 提供了 HSSF 和 XSSF 两个 API,其中 HSSF 用于读写老版本的 BIFF8 格式(Excel 97-2003),XSSF 则针对新的 XML 格式(Excel 2007+)。这两个 API 均具备读取和写入工作表、单元格、公式、样式等功能。读取 Excel 文件时,可通过创建 HSSFWorkbook 或 XSSFWorkbook 对象来打开相应格式的文件,进而遍历工作簿中的每个 Sheet,获取行和列数据。写入 Excel 文件时,创建新的 Workbook 对象,添加 Sheet、Row 和 Cell,即可构建新 Excel 文件。 再看 iTextPDF,它是一个用于生成和修改 PDF 文档的 Java 库,拥有丰富的 API。创建 PDF 文档时,借助 Document 对象,可定义页面尺寸、边距等属性来定制 PDF 外观。添加内容方面,可使用 Paragraph、List、Table 等元素将文本、列表和表格加入 PDF,图片可通过 Image 类加载插入。iTextPDF 支持多种字体和样式,可设置文本颜色、大小、样式等。此外,iTextPDF 的 TextRenderer 类能将 HTML、
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值