【工程师分享】MPSoC VCU Ctrl-SW 2020.2 输出NV12的YUV文件

FPGA开发圈 2021-05-21 12:00

作者:付汉杰,hankf@xilinx.com,文章转载自: 赛灵思中文社区论坛




01
介绍



Xilinx提供超低延时编解码方案,并提供了全套软件。MPSoC Video Codec Unit提供了详细说明。其中的底层应用软件是VCU Control-Software(Ctrl-SW)。


本文主要说明为Ctrl-SW增加输出NV12视频的功能。


1.1. VCU输入和输出格式

Video Codec Unit(VCU) 输入和输出都是是NV12/NV16格式的视频,Y分量存放在一块连续内存区,UV分量交替存放在Y分量后面的连续内存。具体信息,可以参考VCU Product Guide中的“Source Frame Format”和“Memory Format”。


Ctrl-SW的输入文件最好是NV12/NV16格式的视频文件,由于不需要做格式转换,帧率(FPS)最高。但是Ctrl-SW的输出文件缺省是图像真实分辨率的I420/I422的文件,其中的Y、U、V分量,各自存在一块连续内存,UV分量没有像NV12/NV16格式的视频交替在一起。可以使用FFMPeg等工具,将I420的文件,转换成NV12/NV16格式的文件。


1.2. VCU内存的高度和宽度要求

对于视频的输入内存区,VCU要求高和宽都按32向上对齐。对于1920x1080分辨率,输入的buffer大小至少是1920x1088字节;对于3840x2160分辨率,输入的buffer大小至少是3840x2176字节。


对于视频的输出内存区,VCU要求宽以256地址对齐,高以64地址对齐。对于1920x1080分辨率,输出的buffer大小是2048x1088字节;对于3840x2160分辨率,输出的buffer大小是3840x2176字节。


1.3. VCU内存的pitch

视频数据在内存区中存放时,两行之间的数据可以有间隔。对于每个像素的Y分量用8-bit表示的图像,每个像素的Y分量对应内存的一个字节,图像Y分量的每一行对应的内存大小就是其宽度代表的字节数。比如1920x1080,每一行图像的Y分量需要1920字节内存。如果以2048字节来存储一行1920x1080的图像数据,则在前面存放图像数据,后面的数据被VCU忽略。也可以参考PG252的“Figure 7: Frame Buffer Pitch”。




02
显示YUV文件 2.1. 工具RAW yuv player




Github上的RAW yuv player 能显示YUV文件,它的旧版本Sourceforge RAW yuv player在Sourceforge上。RAW yuv player的菜单“Colour”下,有各种颜色格式,菜单“Size”下有各种分辨率;菜单"Zoom"下可以选择图像缩放比例。


RAW yuv player的YUV420(YV12)格式,就是I420格式,可以显示Ctrl-SW缺省输出的YUV文件。RAW yuv player的NV12格式,也是Ctrl-SW的NV12格式,可以显示修改后的Ctrl-SW输出的YUV NV12文件。


2.1.1. 技巧

各种YUV文件,第一片数据一般都是分量Y。如果发现YUV文件的显示有问题,可以设置好分辨率,在菜单“Colour”下选择“Y”,只看其中的分量Y,当成黑白图片看。如果黑白图片是正常的,说明分量Y是对的。


2.2. hexdump

如果图片内容不对,可以使用二进制比较工具比较错误图片和正确图片,比如Beyond Compare。比较的时候,注意取消对齐设置。


如果没有二进制比较工具,可以使用hexdump把YUV文件按HEX格式转换为文本文件,再用文本比较工具,比如kdiff3、meld进行比较。hexdump输出时,会输出星号"*"代替一样的行;多个重复行,也只输出一个星号。为hexdump加上"-v"选项,则会输出所有数据。

xilinx@XSZHANKF$ hexdump -x test_1080p_h264.264.1f.i420.1920x1080.yuv > test_1080p_h264.264.1f.i420.1920x1080.yuv.hex
xilinx@XSZHANKF$ hexdump -v -x test_1080p_h264.264.1f.i420.1920x1080.yuv > test_1080p_h264.264.1f.i420.1920x1080.yuv.v.hex





03
输出NV12/NV16格式文件




如果Ctrl-SW能输出NV12/NV16格式的文件,Ctrl-SW就能直接对自己的文件进行编码,测试时更加方便。


经过研究,在Ctrl-SW 2020.2里,实现了输出NV12/NV16格式文件的功能。


3.1. 选项

Ctrl-SW里有三种分辨率,分别是图像的真实分辨率,Meta数据分辨率,内存块(buffer)分辨率。


图像的真实分辨率,是真实显示的分辨率。


在Ctrl-SW里,为YUV数据分配内存时,根据图像分辨率,并按对齐要求像是对齐图像分辨率后,得到YUV数据的内存块大小,这就是对应的内存块(buffer)分辨率。对于解码,1920x1080分辨率的内存块是2048x1088字节;3840x2160分辨率的buffer是3840x2176字节。


另外分配内存后,每个内存块有一个对应的Meta数据,保存YUV数据的分辨率。Meta数据分辨率可能比内存块分辨率低。1920x1080分辨率的Meta数据分辨率是2048x1088;而3840x2160分辨率的Meta数据分辨率却是3840x2160,在高度上并没有像1080p时向上对齐。


所以输出NV12/NV16的视频时,也有多种组合。为了测试方便,实现了输出各种组合的NV12/NV16的视频。


如果使用选项“-yuv-nvx”,按得到的Meta数据的分辨率信息,从Y和UV分量的地址,逐行写入到文件。


如果使用选项“-yuv-nvx-1buffer”,行依照pitch长度,高使用分辨率的高度并向上按64字节对齐,计算出YUV整个的内存区大小,相当于内存块(buffer)分辨率,一次性写入到文件。


如果使用选项“-yuv-nvx-stride”,行依照pitch长度,高使用分辨率的高度,从Y和UV分量的地址,逐行输出。相当于宽按内存块(buffer)分辨率,高按Meta数据分辨率输出。


如果使用选项“-yuv-nvx-dispay”,按得到的显示分辨率信息,从Y和UV分量的地址,逐行输出。


另外,还附带增加了输出YUV文件时跳帧、抽帧的功能。如果使用选项“--yuv-skip-num”,则前面的指定数量的帧不会被输出;比如指定5,前面的5帧不会被写入到YUV文件。如果使用选项“--yuv-skip-interval”,则指定数字的倍数序号的帧,才会被输出;比如指定数字3,则只有序号是3的倍数的帧才会被写入到YUV文件。




04
代码




在Ctrl-SW 2020.2里,添加如下代码后,可以直接输出NV12/NV16格式的文件。


下面是增加的全局变量定义。

int gi_yuv_output_skip_frame_num=0;
int gi_yuv_output_skip_frame_interval=0;
int gi_yuv_output_nvx_flag=0;
int gi_yuv_output_nvx_1buffer_flag=0;
int gi_yuv_output_nvx_stride_flag=0;
int gi_yuv_output_nvx_dispay_flag=0;
int gi_yuv_output_dispay_width=0;
int gi_yuv_output_dispay_height=0;

下面是增加的ctrlsw_decoder的命令行选项。

opt.addInt("--yuv-skip-num", &gi_yuv_output_skip_frame_num, "Skip frame number before writing YUV file.");
opt.addInt("--yuv-skip-interval", &gi_yuv_output_skip_frame_interval, "Interval frame number when writing YUV file.");
opt.addFlag("-yuv-nvx", &gi_yuv_output_nvx_flag, "Output NV12/NV16 YUV file.", 1);
opt.addFlag("-yuv-nvx-1buffer", &gi_yuv_output_nvx_1buffer_flag, "Output one continuous NV12/NV16 buffer to YUV file.", 1);
opt.addFlag("-yuv-nvx-stride", &gi_yuv_output_nvx_stride_flag, "Output NV12/NV16 YUV file with VCU round-up padding/stride.", 1);
opt.addFlag("-yuv-nvx-dispay", &gi_yuv_output_nvx_dispay_flag, "Output NV12/NV16 YUV file with display width.", 1);


下面是在UncompressedOutputWriter::ProcessFrame()内部增加的判断是否输出NV12/NV16格式的视频文件的判断代码。

if( gi_yuv_output_skip_frame_num_local <  gi_yuv_output_skip_frame_num )
{
return;
}

if( 0 == (gi_yuv_output_skip_frame_num_local%gi_yuv_output_skip_frame_interval) )
{
return;
}

if( ( 1 == gi_yuv_output_nvx_flag ) || ( 1 == gi_yuv_output_nvx_1buffer_flag )
|| ( 1 == gi_yuv_output_nvx_stride_flag ) || ( 1 == gi_yuv_output_nvx_dispay_flag ) )
{
ProcessFrameNVx( tRecBuf, info, iBdOut);
return;
}



下面是显示视频参数的代码,用于调试,可以被屏蔽掉。

void UncompressedOutputWriter::ShowVideoInfo(AL_TBuffer& tRecBuf, AL_TInfoDecode info, int iBdOut)
{

// only print one time.
static int i_call_time=0;
if( 0 != i_call_time )
{
return;
}
i_call_time++;

iBdOut = convertBitDepthToEven(iBdOut);

auto const iSizePix = (iBdOut + 7) >> 3;

TFourCC tRecFourCC = AL_PixMapBuffer_GetFourCC(&tRecBuf);
printFourCC( tRecFourCC, "Recorded frame buffer", __func__, __LINE__ );

int sx = 1, sy = 1;
AL_GetSubsampling(tRecFourCC, &sx, &sy);

int iPitchSrcY = AL_PixMapBuffer_GetPlanePitch(&tRecBuf, AL_PLANE_Y);

int iPitchSrcUV = AL_PixMapBuffer_GetPlanePitch(&tRecBuf, AL_PLANE_UV);
if( iPitchSrcY != iPitchSrcUV )
{
LogInfo("YUV Y Plane pitch: %d does not equal to UV Plane pitch:%d at %s:%d.\n",
iPitchSrcY, iPitchSrcUV, __func__, __LINE__ );
}
LogVerbose("YUV Y Plane pitch:%d, UV Plane pitch:%d at %s:%d.\n", iPitchSrcY, iPitchSrcUV, __func__, __LINE__ );

AL_TDimension tYuvDim = AL_PixMapBuffer_GetDimension(&tRecBuf);
int const iRoundUpYWidth = RoundUp(tYuvDim.iWidth, 256);
if( iPitchSrcY != iRoundUpYWidth )
{
LogInfo("YUV Y Plane pitch %d does not equal to Y Round-up Width:%d at %s:%d.\n",
iPitchSrcY, iRoundUpYWidth, __func__, __LINE__ );
}

// For 1920x1080, YuvDim.iHeight is always rounded up, it is 1920x1088.
// For 3840x2160, YuvDim.iHeight is not rounded up, it is 3840x2160.
int const iRoundUpHeight = RoundUp(tYuvDim.iHeight, 64);
if( tYuvDim.iHeight != iRoundUpHeight )
{
// For 4K video, tYuvDim.iHeight(2160) does not equal to Round-up Height(2176)
LogInfo("YUV Height: %d does not equal to Round-up Height:%d at %s:%d.\n",
tYuvDim.iHeight, iRoundUpHeight, __func__, __LINE__ );
}

//int const iNumPix = tYuvDim.iHeight * tYuvDim.iWidth; // For I420 without extra padding bytes.
const AL_EChromaMode stRecChromaMode = AL_GetChromaMode(tRecFourCC);
//int const iNumPixC = AL_GetChromaMode(tRecFourCC) == AL_CHROMA_MONO ? 0 : ((tYuvDim.iWidth + sx - 1) / sx) * ((tYuvDim.iHeight + sy - 1) / sy);
int const iLineNumPixC = (stRecChromaMode == AL_CHROMA_MONO) ? 0 : ((tYuvDim.iWidth + sx - 1) / sx) ;
int const iRoundUpLineNumPixC = (stRecChromaMode == AL_CHROMA_MONO) ? 0 : ((iPitchSrcUV + sx - 1) / sx) ;

// Get display in sResolutionFound()
int const iNumPix = tYuvDim.iHeight * tYuvDim.iWidth;
int const iRoundUpNumPix = iRoundUpHeight * iPitchSrcY;

int const iNumPixC = iLineNumPixC * ((tYuvDim.iHeight + sy - 1) / sy);
int const iRoundUpNumPixC = iRoundUpLineNumPixC * ((iRoundUpHeight + sy - 1) / sy);
int i_y_buffer_size = iRoundUpNumPix * iSizePix;
int i_uv_buffer_size = 2 * iRoundUpNumPixC * iSizePix;

int i_yuv_buffer_size = i_y_buffer_size + i_uv_buffer_size;
LogVerbose("Subsampling sx:%d, sy:%d at %s:%d.\n", sx, sy, __func__, __LINE__ );
LogVerbose("Height:%d, Width:%d at %s:%d.\n", tYuvDim.iHeight, tYuvDim.iWidth, __func__, __LINE__ );
LogVerbose("Roundup Height:%d, Width:%d at %s:%d.\n", iRoundUpHeight, iPitchSrcY, __func__, __LINE__ );
LogVerbose("iNumPix:%d, iLineNumPixC:%d, iNumPixC:%d, iSizePix:%d at %s:%d.\n", iNumPix, iLineNumPixC, iNumPixC, iSizePix, __func__, __LINE__ );
LogVerbose("iRoundUpNumPix:%d, iRoundUpLineNumPixC:%d, iRoundUpNumPixC:%d at %s:%d.\n", iRoundUpNumPix, iRoundUpLineNumPixC, iRoundUpNumPixC, __func__, __LINE__ );

LogVerbose("NV12/NV16 YUV Plane Y: %d, UV: %d YUV: %d bytes at %s:%d.\n",
i_y_buffer_size, i_uv_buffer_size, i_yuv_buffer_size, __func__, __LINE__ );

uint8_t* p_buff_y_plane = AL_PixMapBuffer_GetPlaneAddress(&tRecBuf, AL_PLANE_Y);
uint8_t* p_buff_uv_plane = AL_PixMapBuffer_GetPlaneAddress(&tRecBuf, AL_PLANE_UV);
LogVerbose("NV12/NV16 YUV Y Plane address: %p, UV Plane address: %p at %s:%d.\n",
p_buff_y_plane, p_buff_uv_plane, __func__, __LINE__ );

int const iOffsetY_UV_Plane = ( (unsigned long long)p_buff_uv_plane - (unsigned long long)p_buff_y_plane);
if( i_y_buffer_size != iOffsetY_UV_Plane )
{
LogInfo("YUV Y Plane sieze: %d does not equal to offset: %d between Y/UV plane at %s:%d.\n",
i_y_buffer_size, iOffsetY_UV_Plane, __func__, __LINE__ );
}

}


下面是增加的输出NV12/NV16格式的视频文件的主体代码。

void UncompressedOutputWriter::ProcessFrameNVx(AL_TBuffer& tRecBuf, AL_TInfoDecode info, int iBdOut)
{

if(!(YuvFile.is_open() || CertCrcFile.is_open()))
return;

static int i_call_time=0;
i_call_time++;

iBdOut = convertBitDepthToEven(iBdOut);

auto const iSizePix = (iBdOut + 7) >> 3;

TFourCC tRecFourCC = AL_PixMapBuffer_GetFourCC(&tRecBuf);

#if 1
ShowVideoInfo( tRecBuf, info, iBdOut);
#endif

int sx = 1, sy = 1;
AL_GetSubsampling(tRecFourCC, &sx, &sy);

int iPitchSrcY = AL_PixMapBuffer_GetPlanePitch(&tRecBuf, AL_PLANE_Y);
int iPitchSrcUV = AL_PixMapBuffer_GetPlanePitch(&tRecBuf, AL_PLANE_UV);

AL_TDimension tYuvDim = AL_PixMapBuffer_GetDimension(&tRecBuf);

const AL_EChromaMode stRecChromaMode = AL_GetChromaMode(tRecFourCC);
int const iLineNumPixC = (stRecChromaMode == AL_CHROMA_MONO) ? 0 : ((tYuvDim.iWidth + sx - 1) / sx) ;

uint8_t* p_buff_y_plane = AL_PixMapBuffer_GetPlaneAddress(&tRecBuf, AL_PLANE_Y);
LogVerbose("NV12/NV16 YUV data Y Plane address: %p at %s:%d.\n", p_buff_y_plane, __func__, __LINE__ );

LogVerbose("YUV data with VCU padding Height:%d, Y Width:%d, UV Width:%d at %s:%d.\n",
tYuvDim.iHeight, iPitchSrcY, iPitchSrcUV, __func__, __LINE__ );

if( 1 == gi_yuv_output_nvx_1buffer_flag )
{

// For 1920x1080, YuvDim.iHeight is always rounded up, it is 1920x1088.
// For 3840x2160, YuvDim.iHeight is not rounded up, it is 3840x2160.
int const iWriteHeight = RoundUp(tYuvDim.iHeight, 64);

//int const iNumPix = tYuvDim.iHeight * tYuvDim.iWidth; // For I420 without extra padding bytes.
int const iRoundUpNumPix = iWriteHeight * iPitchSrcY; // For NV12/NV16 with extra padding bytes.
//int const iNumPixC = AL_GetChromaMode(tRecFourCC) == AL_CHROMA_MONO ? 0 : ((tYuvDim.iWidth + sx - 1) / sx) * ((tYuvDim.iHeight + sy - 1) / sy);
int const iRoundUpLineNumPixC = (stRecChromaMode == AL_CHROMA_MONO) ? 0 : ((iPitchSrcUV + sx - 1) / sx) ;
int const iRoundUpNumPixC = iRoundUpLineNumPixC * ((iWriteHeight + sy - 1) / sy);
int i_y_buffer_size = iRoundUpNumPix * iSizePix;
int i_uv_buffer_size = 2 * iRoundUpNumPixC * iSizePix;
int i_yuv_buffer_size = i_y_buffer_size + i_uv_buffer_size;

// Display YUV file: 1920x1080: 2048x1088; 3840x2160: 3840 x 2176
if( 1 == i_call_time )
{
LogInfo("Diplay NV12/NV16 YUV file of one continuous buffer with Height:%d, Y Width:%d, UV Width:%d at %s:%d.\n",
iWriteHeight, iPitchSrcY, iPitchSrcUV, __func__, __LINE__ );
}
YuvFile.write((const char*)p_buff_y_plane, i_yuv_buffer_size);
}
else
{
int iWriteHeight;
int iWriteYWidth;
int iWriteUVWidth;

// For 1920x1080, YuvDim.iHeight is always rounded up, it is 1920x1088.
// For 3840x2160, YuvDim.iHeight is not rounded up, it is 3840x2160.
if( 1 == gi_yuv_output_nvx_stride_flag )
{
iWriteHeight = tYuvDim.iHeight;
iWriteYWidth = iPitchSrcY;
iWriteUVWidth = 2 * ((iPitchSrcUV + sx - 1) / sx);
LogVerbose("Diplay NV12/NV16 YUV file of stride with Height:%d, Y Width:%d, UV Width:%d at %s:%d.\n",
tYuvDim.iHeight, iPitchSrcY, iPitchSrcUV, __func__, __LINE__ );
}
else
{
if( 0 != gi_yuv_output_dispay_height )
{
// Display YUV file: 1920x1080: 1920x1080.
iWriteHeight = gi_yuv_output_dispay_height;
}
else
{
// Display YUV file: 1920x1080: 1920x1088.
iWriteHeight =tYuvDim.iHeight;
}

if( 0 != gi_yuv_output_dispay_width )
{
iWriteYWidth = gi_yuv_output_dispay_width;
iWriteUVWidth = 2 * ((gi_yuv_output_dispay_width + sx - 1) / sx);
}
else
{
iWriteYWidth =tYuvDim.iWidth;
iWriteUVWidth = 2 * iLineNumPixC;
}

}
if( 1 == i_call_time )
{
LogInfo("Diplay NV12/NV16 YUV file with Height: %d, Y Width: %d, UV Width: %d at %s:%d.\n",
iWriteHeight, iWriteYWidth, iWriteUVWidth, __func__, __LINE__ );
}

// two writes, skipp padding bytes between Y plane and UV plane.
uint8_t* p_buff_y=p_buff_y_plane;
int iYBytes=0;
for( int i=0; i<iWriteHeight; i++ )
{
// Write each line of Y plane, and skipp padding bytes between each line.
YuvFile.write((const char*)p_buff_y, iWriteYWidth);
p_buff_y = p_buff_y + iPitchSrcY;
iYBytes+=iWriteYWidth;
}

uint8_t* p_buff_uv_plane = AL_PixMapBuffer_GetPlaneAddress(&tRecBuf, AL_PLANE_UV);
LogVerbose("NV12/NV16 YUV data UV Plane address: %p at %s:%d.\n", p_buff_uv_plane, __func__, __LINE__ );
uint8_t* p_buff_uv=p_buff_uv_plane;
int iUVBytes=0;
for( int i=0; i<(iWriteHeight/sy); i++ )
{
// Write each line of UV plane, and skipp padding bytes between each line.
YuvFile.write((const char*)p_buff_uv, iWriteUVWidth);
p_buff_uv = p_buff_uv + iPitchSrcUV;
iUVBytes+=iWriteUVWidth;
}
LogVerbose("write NV12/NV16 YUV data Y: %d bytes, UV: %d bytes at %s:%d.\n",
iYBytes, iUVBytes, __func__, __LINE__ );
}
}





05
5. 测试




在开发过程中,测试了1920x1080、3840x2160分辨率的NV12图像。


5.1. 1080分辨率

1920x1080分辨率时,以内存块分辨率输出,分辨率是1920x1088;以pitch长度和分辨率高度向上对齐后输出,分辨率是2048x1088;以pitch长度和Meta分辨率的高度输出,分辨率是2048x1088;以显示分辨率输出,分辨率是1920x1080。如果没有特殊说明,图像都是NV12格式的,也是以NV12格式显示。


查看YUV文件时,必须设置正确的分辨率和格式,否则数据显示会混乱。


以分辨率1920x1080显示选项“-yuv-nvx-dispay”输出的图片,结果正常。


以分辨率2048x1088显示选项“-yuv-nvx-1buffer”输出的图片,结果正常。右边有一块红色图像,是因为对应的内存区没有真实图像数据。


以分辨率2048x1088显示选项“-yuv-nvx-stride”输出的图片,结果正常。右边也有一块红色图像。


5.1.1. 分辨率显示格式错误的现象

以分辨率1920x1080显示分辨率2048x1088图片,图像混乱了。因为实际图像数据每行2048字节,显示时每行1920字节,所以读出的数据混乱了,上面的连续红色块变成了小块,分布到了图像各处。


以分辨率2048x1080显示分辨率2048x1088图片,最上面有绿条,因为把8行的Y分量数据当成了UV分量数据。这8行的实际图像是黑色的。


5.2. 3840x2160分辨率

3840x2160分辨率时,以pitch长度和分辨率高度向上对齐后的分辨率输出,分辨率是3840x2176;其它模式输出,分辨率都是3840x2160。


以分辨率3840x2160显示选项“-yuv-nvx-dispay”输出的图片,结果正常。


以分辨率3840x2176显示选项“-yuv-nvx-1buffer”输出的图片,结果正常。下面有一条绿色,也是因为对应的内存区没有有效的图像数据。


5.2.1. x2160分辨率显示格式错误的现象

以分辨率3840x2176格式显示分辨率3840x2160的图片,最下面有绿条,是因为把部分UV分量数据当成了Y分量数据,导致最下面部分图像缺少UV分量数据。


以分辨率3840x2160、I420格式显示选项“-yuv-nvx-stride”输出的NV12分辨率3840x2176图片,轮廓正常,色彩异常。轮廓正常,是因为对Y分量数据的解析是对的;色彩异常是因为对UV分量数据的解析是错的。




06
未来工作




未来可以继续测试NV16的图像,也可以测试其它分辨率的图像。




07
参考文档




XilinxPG252 (v2020.2) H.264/H.265 Video Codec Unit v1.2 Solution


》》》点击“阅读原文”下载参考文档


关注我们

FPGA开发圈 这里介绍、交流、有关FPGA开发资料(文档下载,技术解答等),提升FPGA应用能力。
评论 (0)
  • 文/Leon编辑/cc孙聪颖‍去年,百度公关部副总裁璩静的争议言论闹得沸沸扬扬,最终以道歉离职收场。时隔一年,百度的高管又出事了。近日,“百度副总裁谢广军女儿开盒孕妇”事件登上热搜,持续发酵,引起网友对百度数据安全性的怀疑。3月19日晚间,百度正式发布声明,表示坚决谴责窃取和公开他人隐私的网络暴力行为,同时强调,百度内部实施匿名化、假名化处理,经查验,泄露数据并非来自百度,而是海外的社工库,“当事人承认家长给她数据库”为不实信息,针对相关谣言百度已经向公安机关报案。然而,并非所有网友都对这份声明
    华尔街科技眼 2025-03-21 21:21 62浏览
  • 人形机器人产业节奏预估:2024年原型机元年,2025年小规模量产元年。当宇树科技H1人形机器人以灵动的手部动作在春晚舞台上演创意融合舞蹈《秧Bot》,舞出"中国智造"时,电视机前十几亿观众第一次深刻意识到:那个需要仰望波士顿动力的时代正在落幕。*图源:宇树科技短短数周后,宇树G1机器人又用一段丝滑的街舞在网络收割亿级播放量,钢铁之躯跳出赛博朋克的浪漫。2月11日,宇树科技在其京东官方旗舰店上架了两款人形机器人产品,型号分别为Unitree H1和G1。2月12日,9.9万元的G1人形机器人首批
    艾迈斯欧司朗 2025-03-22 21:05 89浏览
  • 很多时候我们会以价值来衡量一个人或一件事,也很容易以成败来论定其价值;所谓胜者为王败者为寇,同样的一个人,在成功时是一种评价,如若失败,所得到的又是另一种评断。古训有云:「不以成败论英雄」,成败得失只是一时的胜负,决定胜败的因素很多,无论人、事、时、地、物,都能影响最后的结果,然而结果却不一定是真正最终的价值论断。好比历史上名垂千古的楚汉之争,刘邦最终得胜,开国立业成为汉高祖,然而,刘邦的为人处事、风格操守或是韬略能力,真的就强于项羽吗?其实,刘邦若无萧何、韩信等人鼎力相辅,若非民心一面倒向刘邦
    优思学院 2025-03-21 12:08 27浏览
  • 精益管理的理念和思维是源于日本的丰田模式,虽然精益管理有很多有效而丰有智慧的思想和方法,但在欧美企业要应用精益也并不容易,始终东西方的文化、人民习性都会存在着一点差异。不过,客观来说,精益管理是其优缺点的,以下,优思学院[1]综合吉朱·安东尼(Jiju Antony)教授《中小企业精益六西格玛》一书中的研究略作说明。精益的优点以下是精益生产系统的一些优点(Schonberger,2008):1)积极的劳动力效应。精益战略往往基于员工的主动性,那些从事实际工作的员工才是改善工作的最具创造力的人员。
    优思学院 2025-03-21 15:09 25浏览
  • 在人工智能与物联网技术蓬勃发展的今天,语音交互已成为智能设备的重要功能。广州唯创电子推出的WT3000T8语音合成芯片凭借其高性能、低功耗和灵活的控制方式,广泛应用于智能家居、工业设备、公共服务终端等领域。本文将从功能特点、调用方法及实际应用场景入手,深入解析这款芯片的核心技术。一、WT3000T8芯片的核心功能WT3000T8是一款基于UART通信的语音合成芯片,支持中文、英文及多语种混合文本的实时合成。其核心优势包括:高兼容性:支持GB2312/GBK/BIG5/UNICODE编码,适应不同
    广州唯创电子 2025-03-24 08:42 79浏览
  • 文/Leon编辑/cc孙聪颖‍“无AI,不家电”的浪潮,正在席卷整个家电行业。中国家电及消费电子博览会(AWE2025)期间,几乎所有的企业,都展出了搭载最新AI大模型的产品,从电视、洗衣机、冰箱等黑白电,到扫地机器人、双足机器人,AI渗透率之高令人惊喜。此番景象,不仅让人思考:AI对于家电的真正意义是什么,具体体现在哪些方面?作为全球家电巨头,海信给出了颇有大智慧的答案:AI化繁为简,将复杂留给技术、把简单还给生活,是海信对于AI 家电的终极答案。在AWE上,海信发布了一系列世俱杯新品,发力家
    华尔街科技眼 2025-03-23 20:46 58浏览
  • 文/郭楚妤编辑/cc孙聪颖‍在人工智能与实体经济深度融合的时代浪潮中,究竟何种 AI 产品,方能切实契合用户对美好未来的向往与期待?3 月 20 日,备受全球瞩目的中国家电及消费电子博览会(AWE2025)于上海新国际博览中心盛大开幕。展会首日,长虹重磅推出首款治愈系 AI TV、客餐厅 PRO 共享空调,以及面向低空经济领域的通信模组等一系列创新产品。这一举动充分展现了长虹在家电领域全面推进 AI 化的坚定决心,以及为低空经济等新兴产业提供有力科技支撑的硬核实力 。“首发” 新品,领航用户价值
    华尔街科技眼 2025-03-21 21:13 44浏览
  • 无论你是刚步入职场的新人,还是已经有几年经验的职场老手,培养领导力都是职业发展中一个至关重要的环节。拥有良好的领导能力不仅能让你从人群中脱颖而出,也能让你在团队中成为一个值得信赖、富有影响力的核心成员。什么是领导力?领导力并不仅仅意味着“当老板”或者“发号施令”。它更多地是一种能够影响他人、激发团队潜能,并带领大家实现目标的能力。一位优秀的领导者需要具备清晰的沟通能力、解决问题的能力,以及对人心的深刻理解。他们知道如何激励人心,如何在压力下保持冷静,并能在关键时刻做出正确的决策。如何培养领导力?
    优思学院 2025-03-23 12:24 66浏览
  • 在科技飞速发展的今天,视频监控领域对于高清、稳定、多功能解码芯片的需求与日俱增。现在,一款具有划时代意义的解码芯片——XS9922B 震撼登场,它将为车载监控、倒车影像等应用场景带来全新的变革体验。多协议支持,高清标清一网打尽,XS9922B 作为一款 4 通道模拟复合视频解码芯片,拥有强大的协议兼容性。它不仅支持 HDCCTV 高清协议,让你轻松捕捉高清画面的每一个细节,还兼容 CVBS 标清协议,满足不同设备和场景的多样化需求。无论是 720P/1080P 的高清制式,还是 960H/D1
    芯片徐15652902508 2025-03-21 13:58 20浏览
  • 今年全国两会期间,“体重管理”和“育儿”整体配套政策引发了持久广泛关注。从“吃”到“养”,都围绕着国人最为关心的话题:健康。大家常说“病从口入”,在吃这件事上,过去大家可能更多是为了填饱肚子,如今,消费者从挑选食材到厨电都贯彻着健康的宗旨,吃得少了更要吃得好了。这也意味着在新消费趋势下,谁能抓住众人的心头好,就能带起众人的购买欲望,才能在新一轮竞争中脱颖而出。作为家电行业的风向标,在2025年中国家电及消费电子博览会(AWE)上,这两个话题也被媒体和公众频繁提及。深耕中国厨房三十余年的苏泊尔再次
    华尔街科技眼 2025-03-22 11:42 46浏览
  • 近年来,随着半导体产业的快速发展和技术的不断迭代,物联网设备种类繁多(如智能家居、工业传感器),对算力、功耗、实时性要求差异大,单一架构无法满足所有需求。因此米尔推出MYD-YT113i开发板(基于全志T113-i)来应对这一市场需求。米尔基于全志T113-i核心板及开发板part 01  T113-i芯片及OpenAMP简介T113-i芯片简介T113-i由两颗ARM A7 、一颗C906(RISC-V)和一颗DSP(HIFI 4)组成。C906(RISC-V核)特性:主频
    米尔电子嵌入式 2025-03-21 16:28 30浏览
  • 在智慧城市领域中,当一个智慧路灯项目因信号盲区而被迫增设数百个网关时,当一个传感器网络因入网设备数量爆增而导致系统通信失效时,当一个智慧交通系统因基站故障而导致交通瘫痪时,星型网络拓扑与蜂窝网络拓扑在构建广覆盖与高节点数物联网网络时的局限性便愈发凸显,行业内亟需一种更高效、可靠与稳定的组网技术以满足构建智慧城市海量IoT网络节点的需求。星型网络的无线信号覆盖范围高度依赖网关的部署密度,同时单一网关的承载设备数量有限,难以支撑海量IoT网络节点的城市物联系统;而蜂窝网络的无线信号覆盖范围同样高度依
    华普微HOPERF 2025-03-24 17:00 76浏览
  • 在智能终端设备快速普及的当下,语音交互已成为提升用户体验的关键功能。广州唯创电子推出的WT3000T8语音合成芯片,凭借其卓越的语音处理能力、灵活的控制模式及超低功耗设计,成为工业控制、商业终端、公共服务等领域的理想选择。本文将从技术特性、场景适配及成本优势三方面,解析其如何助力行业智能化转型。一、核心技术优势:精准、稳定、易集成1. 高品质语音输出,适配复杂环境音频性能:支持8kbps~320kbps宽范围比特率,兼容MP3/WAV格式,音质清晰自然,无机械感。大容量存储:内置Flash最大支
    广州唯创电子 2025-03-24 09:08 108浏览
  • 核心板简介创龙科技 SOM-TL3562 是一款基于瑞芯微 RK3562J/RK3562 处理器设计的四核 ARM C ortex-A53 + 单核 ARM Cortex-M0 全国产工业核心板,主频高达 2.0GHz。核心板 CPU、R OM、RAM、电源、晶振等所有元器件均采用国产工业级方案,国产化率 100%。核心板通过 LCC 邮票孔 + LGA 封装连接方式引出 MAC、GMAC、PCIe 2.1、USB3.0、 CAN、UART、SPI、MIPI CSI、MIPI
    Tronlong 2025-03-24 09:59 103浏览
我要评论
0
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦