Broadcom Nexus学习(四):Video Decoder

2023-12-13 19:40

本文主要是介绍Broadcom Nexus学习(四):Video Decoder,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

之前研究了Nexus Graphics,Audio Playback, AudioDecoder等。现在需要研究VideoDecoder。

 

先看图示:

 

 

此图显示了以有线电视为源,如何一步步通过各个 Interface接到输出去的。

 

InputBand是有线电视输入源,ParserBand则是解析器。 PidChannel分为Video和Audio。分别将Video和Audio数据传输向Video DecoderAudioDecoder。之后,Audio如上一章所讲进入Mixer到DAC。

而Video则通过VideoDecoder解压后显示于DisplayVideoWindow上。

 

代码流程如下:

1. NEXUS_Platform_GetStreamerInputBand(0, &inputBand);

从Platform处得到Streamer InputBand,Platform将参数1(index)0 设置为Tune Stream。

所以参数2(inputBand)返回的是一个InputBand。 它就是Tune Stream。 即位Tune 传入的有线电视信号。

 

2. 设置Parser: 

parserBand = NEXUS_ParserBand_e0;
NEXUS_ParserBand_GetSettings(parserBand, &parserBandSettings);
parserBandSettings.sourceType = NEXUS_ParserBandSourceType_eInputBand;
parserBandSettings.sourceTypeSettings.inputBand = inputBand;
parserBandSettings.transportType = NEXUS_TransportType_eTs;
NEXUS_ParserBand_SetSettings(parserBand, &parserBandSettings);

 

3. videoPidChannel = NEXUS_PidChannel_Open(parserBand, 0x11, NULL);

打开Pid Channel from parser band.

前面有了ParserBand,并指定了ParserBand的InputBand。这里则打开PidChannel,输入为此ParserBand。

(此处参数2的PID为0x11,这个值与音视频流有关,见后面的讲解。)

 

 

4. 设置VideoDecoder:

NEXUS_VideoDecoder_GetDefaultStartSettings(&videoProgram);
videoProgram.codec = NEXUS_VideoCodec_eMpeg2;
videoProgram.pidChannel = videoPidChannel;

 

5. 创建Display并于Platform Output 连接:

NEXUS_Display_GetDefaultSettings(&displaySettings);
 displaySettings.format = NEXUS_VideoFormat_eNtsc;
 display = NEXUS_Display_Open(0, &displaySettings);
 NEXUS_Display_AddOutput(display, NEXUS_ComponentOutput_GetConnector(platformConfig.outputs.component[0]));
 NEXUS_Display_AddOutput(display, NEXUS_CompositeOutput_GetConnector(platformConfig.outputs.composite[0]));
 if (platformConfig.outputs.svideo[0]) {
     NEXUS_Display_AddOutput(display, NEXUS_SvideoOutput_GetConnector(platformConfig.outputs.svideo[0]));
 }

 

6. 创建VideoWindow:

window = NEXUS_VideoWindow_Open(display, 0);

Open a VideoWindow from its Display.

 

7. 打开VideoDecoder,并将其连接到Video Windows。

vdecode = NEXUS_VideoDecoder_Open(0, NULL);
NEXUS_VideoWindow_AddInput(window, NEXUS_VideoDecoder_GetConnector(vdecode));

 

8. 开始Decoder:

NEXUS_VideoDecoder_Start(vdecode, &videoProgram);

 

 

9. 关闭:

NEXUS_VideoDecoder_Stop(vdecode);
 NEXUS_VideoWindow_RemoveAllInputs(window);
 NEXUS_VideoInput_Shutdown(NEXUS_VideoDecoder_GetConnector(vdecode));
 NEXUS_VideoWindow_Close(window);
 NEXUS_Display_Close(display);
 NEXUS_VideoDecoder_Close(vdecode);
 NEXUS_PidChannel_Close(videoPidChannel);

 

 

 具体过程很简单:

 1.得到Index为0的StreamerInputBand。即是Tune的输入。

 2.设置ParserBand。将inputBand设置为ParserBand的Input。

 3.打开Video And Audio Pid Channel. NEXUS_PidChannel_Open();

   Open a new PID channel from a parser band.

   其中参数2:PID:PID (packet ID) that will be selected from the parser band. If TS, this is a PID. If PES, this is a PES stream id.

   这个PID的数值,与具体音频视频格式有关。例如,TS流,PS流中各不相同。

   有个软件叫做:MediaInfo:它可以查看指定音视频文件的Video,Audio ID。

 

 4. 设置VideoDecoder AudioDecoder的StartSetting。 

    主要设置codec(视频音频格式)和pidChannel(先前建立的Pid Channel)。

 

 5. 打开AudioDecoder,并将其连接到AudioDAC上。

 6. 设置,建立Display.并将Display连接到Display Output(分量,HDMI,混合,S-Video)

 7. Open a VideoWindow from its Display. index=0.(NEXUS_VideoWindow_Open)

 8. Open a new VideoDecoder.. (NEXUS_VideoDecoder_Open). 并将VideoDecoder加入为VideoWindow的Input。(NEXUS_VideoWindow_AddInput)

 9. 开始播放:NEXUS_VideoDecoder_Start,NEXUS_AudioDecoder_Start。

 

 

 

 

 到这里,从Tune中输入出Video,Audio已经完成了。但大家会想,是否可以像之前播放本地Audio那样播放本地的Video File呢?当然是可以的,PlayPump就是做这事的。(Audio Decoder中有对应音频的例子 http://blog.csdn.net/amor2006/archive/2011/04/04/6302203.aspx

 

思路与之前Audio Decoder类似:

打开,PlayPump, Playback,将PlayPump设置为数据源,利用Playback打开PidChannel。并将PidChannel与VideoDecoder, AudioDecoder联系起来。再将VideoDecoder连到Display的VideoWindow上,通过Display的Output显示在TV上。 AudioDecoder连到Mixer, Mixer中与AudioPlayback混和后进入AudioDAC。

 

先看图示:

 

 

下面看具体步骤:

 

1. 创建PlayPump, Playback:

playpump = NEXUS_Playpump_Open(0, NULL);

playback = NEXUS_Playback_Create();


讲解:

NEXUS_PlaypumpHandle NEXUS_Playpump_Open(
                unsigned index, const NEXUS_PlaypumpOpenSettings *pSettings )

打开一个Playpump Interface。

Open a new Playpump interface.

Broadcom7413支持5个Playpump。 所以Index不能超过4。

 

NEXUS_PlaybackHandle NEXUS_Playback_Create(void)

创建一个Playback实例。Create a new playback instance.

我们创建这个Playback,用来打开PID Channel。

 

2. 使用Nexus接口打开视频文件:

file = NEXUS_FilePlay_OpenPosix(fname, NULL);

此FilePlayHandle用来传递给Playback供输入数据源。

 

3. 设置Playback:

这里主要是设置PlayPump为Playback的playpump. 并设置Playpump的数据传输格式。

NEXUS_Playback_GetSettings(playback, &playbackSettings);
playbackSettings.playpump = playpump;  //此处设置playback 的playpump, 用来给Decoder填充数据。

//数据传输格式,包括:MPEG1,DVD VOB,MPEG2-TS(基于传输的),MPEG2-PS(基于存储的)

playbackSettings.playpumpSettings.transportType = NEXUS_TransportType_eTs;

NEXUS_Playback_SetSettings(playback, &playbackSettings);

 

在使用MediaInfo软件查看目标视频时发现,它是MPEG2-PS。所以修改如下:

playbackSettings.playpumpSettings.transportType = NEXUS_TransportType_eMpeg2Pes;

 

 

4. 创建AudioDecoder,并将其连接到DAC:

audioDecoder = NEXUS_AudioDecoder_Open(0, NULL);
NEXUS_AudioOutput_AddInput(
        NEXUS_AudioDac_GetConnector(platformConfig.outputs.audioDacs[0]),
        NEXUS_AudioDecoder_GetConnector(audioDecoder, NEXUS_AudioDecoderConnectorType_eStereo));

其实此处AudioDecoder也可以连接到Mixer中。

 

5. 打开Display并指定其Output:

display = NEXUS_Display_Open(0, NULL);

NEXUS_Display_AddOutput(display, NEXUS_ComponentOutput_GetConnector(platformConfig.outputs.component[0]));

 

 

6. 创建VideoWindow, VideoDecoder,并将VideoDecoder设置为VideoWindow的Input:

window = NEXUS_VideoWindow_Open(display, 0);
videoDecoder = NEXUS_VideoDecoder_Open(0, NULL);
NEXUS_VideoWindow_AddInput(window, NEXUS_VideoDecoder_GetConnector(videoDecoder));

 

7. 利用Playback,打开Video PidChannel, Audio PidChannel:

NEXUS_Playback_GetDefaultPidChannelSettings(&playbackPidSettings);

playbackPidSettings.pidSettings.pidType = NEXUS_PidType_eVideo;
playbackPidSettings.pidTypeSettings.video.codec = NEXUS_VideoCodec_eMpeg2;     playbackPidSettings.pidTypeSettings.video.index = true;
playbackPidSettings.pidTypeSettings.video.decoder = videoDecoder;

videoPidChannel = NEXUS_Playback_OpenPidChannel(playback, 0x21, &playbackPidSettings);

 

NEXUS_Playback_GetDefaultPidChannelSettings(&playbackPidSettings);
playbackPidSettings.pidSettings.pidType = NEXUS_PidType_eAudio;
playbackPidSettings.pidSettings.pidTypeSettings.audio.codec = NEXUS_AudioCodec_eMpeg;

playbackPidSettings.pidTypeSettings.audio.primary = audioDecoder;
audioPidChannel = NEXUS_Playback_OpenPidChannel(playback, 0x22, &playbackPidSettings);

 

首先得到Playback的Default PidChannel的设置,

1.分别指定其PlayPump的Type为Video和Audio。

2.分别指定PlayPump的Codec格式为:NEXUS_VideoCodec_eMpeg2,NEXUS_AudioCodec_eMpeg。即为:MPEG2-Vidoe和MPEG1/2 -layer 1/2.

3.分别指出PID Channel的Video和Audio的解码器。注意,他们指定的Struct其实并不对应。

4。利用PlayBack打开PidChannel:

注意:PID分别为0x21,0x22. 此处PID与具体媒体格式对应。可以使用MedioInfo查看。

查到自己的视频文件为:0xE0,0xC0.

 

 

8. 设置VideoDecoder和AudioDecoder的StrartSetting,并指定各自的PIDChannel:

    NEXUS_VideoDecoder_GetDefaultStartSettings(&videoProgram);
    videoProgram.codec = NEXUS_VideoCodec_eMpeg2;
    videoProgram.pidChannel = videoPidChannel;

    NEXUS_AudioDecoder_GetDefaultStartSettings(&audioProgram);
    audioProgram.codec = NEXUS_AudioCodec_eMpeg;
    audioProgram.pidChannel = audioPidChannel;

 

指定VideoDecoder Codec和AudioDecoder Codec的格式。即解码器的格式。并指定各自的PIDChannel。

之前PIDChannel得到了VideoDecoder和AudioDecoder。

现在AudioDecoder,VideoDecoder得到对应PIDChannel。有点相互确认的意思。呵呵。

 

 

9. 正式开始解码和播放:

    NEXUS_VideoDecoder_Start(videoDecoder, &videoProgram);
    NEXUS_AudioDecoder_Start(audioDecoder, &audioProgram);
    NEXUS_Playback_Start(playback, file, NULL);

 

 

如果不处理,会循环播放。可以利用playbackSettings.endOfStreamCallback.callback察看是否播放完毕。完毕则退出。

 

 

10。退出:

NEXUS_VideoDecoder_Stop(videoDecoder);
    NEXUS_AudioDecoder_Stop(audioDecoder);
    NEXUS_Playback_Stop(playback);
    NEXUS_FilePlay_Close(file);
    NEXUS_Playback_Destroy(playback);
    NEXUS_Playpump_Close(playpump);
    NEXUS_VideoInput_Shutdown(NEXUS_VideoDecoder_GetConnector(videoDecoder));
    NEXUS_VideoDecoder_Close(videoDecoder);
    NEXUS_AudioOutput_RemoveAllInputs(NEXUS_AudioDac_GetConnector(platformConfig.outputs.audioDacs[0]));
    NEXUS_AudioOutput_RemoveAllInputs(NEXUS_SpdifOutput_GetConnector(platformConfig.outputs.spdif[0]));
    NEXUS_AudioInput_Shutdown(NEXUS_AudioDecoder_GetConnector(audioDecoder, NEXUS_AudioDecoderConnectorType_eStereo));
    NEXUS_AudioDecoder_Close(audioDecoder);
    NEXUS_Display_Close(display);

这篇关于Broadcom Nexus学习(四):Video Decoder的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/489732

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

线性代数|机器学习-P36在图中找聚类

文章目录 1. 常见图结构2. 谱聚类 感觉后面几节课的内容跨越太大,需要补充太多的知识点,教授讲得内容跨越较大,一般一节课的内容是书本上的一章节内容,所以看视频比较吃力,需要先预习课本内容后才能够很好的理解教授讲解的知识点。 1. 常见图结构 假设我们有如下图结构: Adjacency Matrix:行和列表示的是节点的位置,A[i,j]表示的第 i 个节点和第 j 个

Node.js学习记录(二)

目录 一、express 1、初识express 2、安装express 3、创建并启动web服务器 4、监听 GET&POST 请求、响应内容给客户端 5、获取URL中携带的查询参数 6、获取URL中动态参数 7、静态资源托管 二、工具nodemon 三、express路由 1、express中路由 2、路由的匹配 3、路由模块化 4、路由模块添加前缀 四、中间件