VENC 通道属性配置参数理解

本文详细介绍了音视频编码中常见的几种编码格式(H.264、MJPEG、JPEG、MPEG4)及其特点,并深入探讨了编码属性配置、码率控制属性配置等内容,包括CBR、VBR、ABR等码率控制模式。

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

配置参数的结构体是

typedef struct hiVENC_CHN_ATTR_S 


    VENC_ATTR_S     stVeAttr; 
    VENC_RC_ATTR_S stRcAttr; 
}VENC_CHN_ATTR_S; 


stVeAttr  :编码属性

stRcAttr :码率控制属性



编码属性:

typedef struct hiVENC_ATTR_S 

    PAYLOAD_TYPE_E  enType; 
    union 


        VENC_ATTR_H264_S  stAttrH264e; 
        VENC_ATTR_MJPEG_S stAttrMjpeg; 
        VENC_ATTR_JPEG_S  stAttrJpeg; 
        VENC_ATTR_MPEG4_S stAttrMpeg4; 
    };     
}VENC_ATTR_S; 


enType :选择编码类型  有H264 Mjpeg jpeg MPEG4


H.264是国际标准化组织(ISO)和国际电信联盟(ITU)共同提出的继MPEG4之后的新一代数字视频压缩格式

1.低码率(Low Bit Rate):和MPEG2和MPEG4 ASP等压缩技术相比,在同等图像质量下,采用H.264技术压缩后的数据量只有MPEG2的1/8,MPEG4的1/3。[1] 
2.高质量的图像:H.264能提供连续、流畅的高质量图像(DVD质量)。[1] 
3.容错能力强:H.264提供了解决在不稳定网络环境下容易发生的丢包等错误的必要工具。[1] 
4.网络适应性强:H.264提供了网络抽象层(Network Abstraction Layer),使得H.264的文件能容易地在不同网络上传输(例如互联网,CDMA,GPRS,WCDMA,CD MA2000等)

MJPEG是24-bit的"true-color"影像标准,MJPEG的工作是将RGB格式的影像转换成YCrCB格式,目的是为了减少档案大小,一般约可减少1/3~1/2左右

M-JPEG是一种基于静态图像压缩技术JPEG发展起来的动态图像压缩技术,可以生成序列化的运动图像。其主要特点是基本不考虑视频流中不同帧之间的变化,只单独对 某一帧进行压缩,其压缩倍数为20~80倍,适合静态画面的压缩,分辨率可从352×288到704×576

M-JPEG的主要缺点是压缩效率低,MJPEG算法是根据每一帧图像的内容进行压缩,而不是根据相邻帧图像之间的差异来进行压缩,因此造成了大量冗余信息被重复存储, 存储占用的空间大到每帧8~15K字节,最好也只能做到每帧3K字节,但如果因此而采用高压缩比则视频质量会严重降低


JPEG 是Joint Photographic Experts Group(联合图像专家小组)的缩写,是第一个国际图像压缩标准。JPEG图像压缩算法能够在提供良好的压缩性能的同时,具有比较好的重建质量,被广泛应用于图像、视频处理领域。

优点:摄影作品或写实作品支持高级压缩。
   利用可变的压缩比可以控制文件大小。
     支持交错(对于渐近式JPEG文件)。
       广泛支持Internet标准。
缺点:有损耗压缩会使原始图片数据质量下降。
   当您编辑和重新保存JPEG文件时,JPEG会混合原始图片数据的质量下降。这种下降是累积性的。
  JPEG不适用于所含颜色很少、具有大块颜色相近的区域或亮度差异十分明显的较简单的图片

MPEG全称是Moving Pictures Experts Group(动态图象专家组),是国际标准化组织(ISO)成立的专责制定有关运动图像压缩编码标准的工作组,所制定的标准是国际通用标准,叫MPEG标准

MPEG4之优势在于其压缩比(最大可达4000:1),低位元速率,较少之核心程式空间,加强运算功能,及强大之通讯应用整合能力,己成为影音数位视讯产业,最重要之  功及标准格式


H264 编码属性配置

typedef struct hiVENC_ATTR_H264_S 

HI_U32  u32MaxPicWidth; 
    HI_U32  u32MaxPicHeight; 
    HI_U32  u32BufSize; 
    HI_U32  u32Profile; 
    HI_BOOL bByFrame; 
    HI_S32  bField; 
    HI_S32  bMainStream; 
    HI_U32  u32Priority; 
HI_BOOL bVIField; 
    HI_U32  u32PicWidth; 
    HI_U32  u32PicHeight; 
}VENC_ATTR_H264_S; 


MJPG 编码属性配置

typedef struct hiVENC_ATTR_MJPEG_S 

HI_U32  u32MaxPicWidth; 
HI_U32  u32MaxPicHeight; 
HI_U32 u32BufSize; 
HI_BOOL bByFrame; 
HI_BOOL bMainStream; 
HI_BOOL bVIField; 
HI_U32 u32Priority; 
HI_U32 u32PicWidth; 
HI_U32 u32PicHeight;

}VENC_ATTR_MJPEG_S; 


。。


几个格式通道属性配置都一样


码率控制属性

typedef struct hiVENC_RC_ATTR_S 

VENC_RC_MODE_E       enRcMode; 
union 
    { 
VENC_ATTR_H264_CBR_S    stAttrH264Cbr; 
        VENC_ATTR_H264_VBR_S    stAttrH264Vbr; 
        VENC_ATTR_H264_FIXQP_S  stAttrH264FixQp; 
VENC_ATTR_H264_ABR_S     stAttrH264Abr; 
VENC_ATTR_MPEG4_VBR_S   stAttrMpeg4Vbr; 
        VENC_ATTR_MPEG4_FIXQP_S  stAttrMpeg4FixQp; 
      VENC_ATTR_MPEG4_CBR_S   stAttrMpeg4Cbr; 
        VENC_ATTR_MJPEG_FIXQP_S  stAttrMjpegeFixQp; 
        VENC_ATTR_MJPEG_CBR_S   stAttrMjpegeCbr; 
        VENC_ATTR_MJPEG_VBR_S stAttrMjpegeVbr; 
    }; 
    HI_VOID*       pRcAttr ; 
  
}VENC_RC_ATTR_S;


可以看到 这里面主要是 CBR VBR ABR FIXQP 这几个码率类型


CBR编码
  在流式播放方案中使用CBR编码最为有效。使用CBR编码时,比特率在流的进行过程中基本保持恒定并且接近目标比特率,始终处于由缓冲区大小确定的时间窗内。CBR编码的缺点在于编码内容的质量不稳定。因为内容的某些片段要比其他片段更难压缩,所以CBR流的某些部分质量就比其他部分差。此外,CBR编码会导致相邻流的质量不同。通常在较低比特率下,质量的变化会更加明显。采用CBR编码方式时节目合成时间会短一些,但文件的长度会大一些(即相同时长的节目会占用更多的空间或者相同的空间只能容纳更短的节目)。

VBR编码
  当计划提供内容供用户下载、 将内容在本地播放或者在读取速度有限的设备(如CD或DVD播放机)上播放时,请使用VBR编码。(计划流式播放内容时也可以采用峰值VBR编码模式)当 编码内容中混有简单数据和复杂数据(例如,在快动作和慢动作间切换的视频)时,VBR 编码是很有优势的。使用VBR编码时,系统将自动为内容的简单部分分配较少的比特,从而留出足量的比特用于生成高质量的复杂部分。这意味着复杂性恒定的内 容(例如新闻播音)不会受益于VBR编码。对混合内容使用 VBR 编码时,在文件大小相同的条件下,VBR编码的输出结果要比CBR编码的输出结果质量好得多。在某些情况下,与CBR编码文件质量相同的VBR编码文件, 其大小可能只有前者的一半。

ABR
平均比特率,是VBR的一种插值参数。Lame针对CBR不佳的文件体积比和VBR生成文件大小不定的特点独创了这种编码模式。ABR也 被称为“Safe VBR”,它是在指定的平均Bitrate内,以每50帧(30帧约1秒)为一段,低频和不敏感频率使用相对低的流量,高频和大动态表现时使用高流量。举例来说,当指定用192kbps ABR对一段wav文件进行编码时,Lame会将该文件的85%用192kbps固定编码,然后对剩余15%进行动态优化:复杂部分用高于192kbps 来编码、简单部分用低于192kbps来编码。与192kbps CBR相比,192kbps ABR在文件大小上相差不多,音质却提高不少。ABR编码在速度上是VBR编码的2到3倍,在128-256kbps范围内质量要好于CBR。可以做为VBR和CBR的一种折衷选择。



这个根据 自己的要求配置相应的参数




XMEDIA_S32 rgn_handle_create(struct test_resource *res) { // printf("into %s\n", __func__); XMEDIA_S32 s32Ret = XMEDIA_SUCCESS; res->rgn_handle_num = 1; res->rgn_handle[0] = 0; RGN_ATTR_S stRgnAttr; stRgnAttr.enType = OVERLAY_RGN; stRgnAttr.unAttr.stOverlay.enPixelFmt = PIXEL_FORMAT_ARGB_1555; // stRgnAttr.unAttr.stOverlay.enPixelFmt = PIXEL_FORMAT_ARGB_8888; // stRgnAttr.unAttr.stOverlay.stSize.u32Width = 570; //调整背景的大小 // stRgnAttr.unAttr.stOverlay.stSize.u32Height = 60; stRgnAttr.unAttr.stOverlay.stSize.u32Width = OVERLAY_WIDTH; // 调整背景的大小 stRgnAttr.unAttr.stOverlay.stSize.u32Height = OVERLAY_HEIGHT; stRgnAttr.unAttr.stOverlay.u32BgColor = 0x00ffffff; stRgnAttr.unAttr.stOverlay.u32CanvasNum = 1; s32Ret = XMEDIA_API_RGN_Create(res->rgn_handle[0], &stRgnAttr); if (s32Ret != XMEDIA_SUCCESS) { DEMO_PRINT("XMEDIA_API_RGN_Create faild with%#x!\n", s32Ret); return s32Ret; } return s32Ret; } XMEDIA_S32 rgn_bind_chn(struct test_resource *res) { // printf("into %s\n", __func__); XMEDIA_S32 s32Ret = XMEDIA_SUCCESS; RGN_CHN_ATTR_S stChnAttr; MPP_CHN_S stChn; // 与set_rgn_display_conf相同 stChn.enModId = MOD_ID_VENC; stChn.s32DevId = 0; stChn.s32ChnId = res->venc_chn[0]; // stChn.s32ChnId = res->venc_chn[1]; stChnAttr.bShow = XMEDIA_TRUE; stChnAttr.enType = OVERLAY_RGN; // 叠加层的起始坐标设为左上角 (0, 0),可能基于视频分辨率定位。 stChnAttr.unChnAttr.stOverlayChn.stPoint.s32X = 0; stChnAttr.unChnAttr.stOverlayChn.stPoint.s32Y = 0; // 层级为0,可能表示该叠加层位于最底层,或被其他高层级图层覆盖。 stChnAttr.unChnAttr.stOverlayChn.u32Layer = 0; // 前景透明度(FgAlpha):叠加内容(如文字、图形)的半透明程度 stChnAttr.unChnAttr.stOverlayChn.u32FgAlpha = 64; // 背景透明度(BgAlpha):叠加层背景的半透明程度(128为0%透明度)。 stChnAttr.unChnAttr.stOverlayChn.u32BgAlpha = 128; stChnAttr.unChnAttr.stOverlayChn.stQpInfo.bQpDisable = XMEDIA_FALSE; stChnAttr.unChnAttr.stOverlayChn.stQpInfo.bAbsQp = XMEDIA_TRUE; stChnAttr.unChnAttr.stOverlayChn.stQpInfo.s32Qp = 30; stChnAttr.unChnAttr.stOverlayChn.stInvertColor.stInvColArea.u32Height = 16; stChnAttr.unChnAttr.stOverlayChn.stInvertColor.stInvColArea.u32Width = 16; stChnAttr.unChnAttr.stOverlayChn.stInvertColor.u32LumThresh = 128; stChnAttr.unChnAttr.stOverlayChn.stInvertColor.enChgMod = LESSTHAN_LUM_THRESH; stChnAttr.unChnAttr.stOverlayChn.stInvertColor.bInvColEn = XMEDIA_FALSE; stChnAttr.unChnAttr.stOverlayChn.enAttachDest = ATTACH_JPEG_MAIN; // 是否需要设置? MPP_CHN_S stChnAttr.unChnAttr.stOverlayChn.stPoint.s32X = 0; stChnAttr.unChnAttr.stOverlayChn.stPoint.s32Y = 0; s32Ret = XMEDIA_API_RGN_AttachToChn(res->rgn_handle[0], &stChn, &stChnAttr); if (s32Ret != XMEDIA_SUCCESS) { DEMO_PRINT("XMEDIA_API_RGN_AttachToChn faild with%#x!\n", s32Ret); return s32Ret; } return s32Ret; } XMEDIA_S32 rgn_add(struct test_resource *res, const char *str) { // printf("into %s\n", __func__); // printf("str:%s\n", str); int height = OVERLAY_HEIGHT; int width = OVERLAY_WIDTH; XMEDIA_S32 ret = XMEDIA_SUCCESS; BITMAP_S stBitmap; SIZE_S stSize; // #if 0 float fontSize = FONTSIZE; unsigned short *addr = string2bitmap(str, &fontSize, width, height); if (addr == NULL) { // printf("Bitmap generated is ready\n"); printf("Failed to generate bitmap.\n"); } // sleep(1); // 获取字符串转换为bitmap // add 1. #if 1 // setbit是会多复制一边内存的 // add 2. // printf("addr(%p)\n", addr); stBitmap.pData = addr; // 要放的内存 或者处理好的图片直接放这 stBitmap.enPixelFormat = PIXEL_FORMAT_ARGB_1555; // stBitmap.u32Width = width; // 宽 stBitmap.u32Height = height; // 高 ret = XMEDIA_API_RGN_SetBitMap(res->rgn_handle[0], &stBitmap); free(addr); if (ret != XMEDIA_SUCCESS) { free(stBitmap.pData); DEMO_PRINT("XMEDIA_API_RGN_SetBitMap faild with%#x!\n", ret); return ret; } #endif #if 0 ret = XMEDIA_API_RGN_GetCanvasInfo(res->rgn_handle[0], &res->rgn_canvasInfo); if (XMEDIA_SUCCESS != ret) { printf("XMEDIA_API_RGN_GetCanvasInfo fail! ret: 0x%x.\n", ret); return NULL; } // res->rgn_canvasInfo.u64VirtAddr = addr; // stBitmap.pData = addr; stBitmap.pData = (XMEDIA_VOID*)(XMEDIA_UL)res->rgn_canvasInfo.u64VirtAddr; stSize.u32Width = res->rgn_canvasInfo.stSize.u32Width; stSize.u32Height = res->rgn_canvasInfo.stSize.u32Height; unsigned short *pData_ptr = (unsigned short *)stBitmap.pData; unsigned short *addr_ptr = (unsigned short *)addr; // for (int i = 0; i < height; i++) // { // for (int j = 0; j < width; j++) // { // // stBitmap.pData[i * width + j] = addr[i * width + j]; // pData_ptr[i * width + j] = addr_ptr[i * width + j]; // } // } // printf("stSize.u32Width=%d stSize.u32Height=%d\n", stSize.u32Width, stSize.u32Height); if(XMEDIA_NULL == stBitmap.pData) { return XMEDIA_FAILURE; } memcpy(stBitmap.pData, addr, 570 * 60 * 3 * sizeof(unsigned char)); // bitmap_bytes使用字符串转换为bitmap然后放进去得了 //memset(stBitmap.pData, addr, 570 * 60 * 3 * sizeof(unsigned char)); // 处理bitmap // REGION_MST_UpdateCanvas("STB.bmp", &stBitmap, XMEDIA_FALSE, 0, &stSize, res->rgn_canvasInfo.u32Stride, PIXEL_FORMAT_ARGB_1555); ret = XMEDIA_API_RGN_UpdateCanvas(res->rgn_handle[0]); if (XMEDIA_SUCCESS != ret) { printf("XMEDIA_API_RGN_UpdateCanvas fail! ret: 0x%x.\n", ret); return NULL; } #endif } // 前提 区域必须先叠加到通道上 XMEDIA_S32 set_rgn_display_conf(struct test_resource *res) { XMEDIA_S32 s32Ret = XMEDIA_SUCCESS; MPP_CHN_S stChn; RGN_ATTR_S stRgnAttr; RGN_CHN_ATTR_S stChnAttr; stChn.enModId = MOD_ID_VENC; stChn.s32DevId = 0; stChn.s32ChnId = res->venc_chn[0]; // stChn.s32ChnId = res->venc_chn[1]; s32Ret = XMEDIA_API_RGN_GetDisplayAttr(res->rgn_handle[0], &stChn, &stChnAttr); if (s32Ret != XMEDIA_SUCCESS) { return s32Ret; } stChnAttr.bShow = XMEDIA_TRUE; stChnAttr.enType = OVERLAY_RGN; stChnAttr.unChnAttr.stOverlayChn.stPoint.s32X = 0; stChnAttr.unChnAttr.stOverlayChn.stPoint.s32Y = 0; stChnAttr.unChnAttr.stOverlayChn.u32BgAlpha = 160; stChnAttr.unChnAttr.stOverlayChn.u32FgAlpha = 160; stChnAttr.unChnAttr.stOverlayChn.u32Layer = 0; stChnAttr.unChnAttr.stOverlayChn.stQpInfo.bAbsQp = XMEDIA_FALSE; stChnAttr.unChnAttr.stOverlayChn.stQpInfo.s32Qp = 0; s32Ret = XMEDIA_API_RGN_SetDisplayAttr(res->rgn_handle[0], &stChn, &stChnAttr); if (s32Ret != XMEDIA_SUCCESS) { return s32Ret; } return s32Ret; } XMEDIA_S32 rgn_unbind_chn(struct test_resource *res) { // printf("into rgn_unbind_chn\n"); XMEDIA_S32 s32Ret = XMEDIA_SUCCESS; MPP_CHN_S stChn; stChn.enModId = MOD_ID_VENC; stChn.s32DevId = 0; stChn.s32ChnId = res->venc_chn[0]; // stChn.s32ChnId = res->venc_chn[1]; s32Ret = XMEDIA_API_RGN_DetachFromChn(res->rgn_handle[0], &stChn); if (s32Ret != XMEDIA_SUCCESS) { DEMO_PRINT("XMEDIA_API_RGN_DetachFromChn faild with%#x!\n", s32Ret); return s32Ret; } return s32Ret; }注释一下代码
最新发布
07-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值