CANN媒体数据处理V2,JPEGD接口介绍
【摘要】 这是媒体数据处理的第二篇博客,关于JPEG解码传送门第一篇文章流程图注意此图有乾坤,我们之前接触到的不管是媒体数据处理V1还是v2的其它功能接口,都是可以在单线程与多线程之间自由选择的,而仔细看这幅图,标明用户需要重新起一个新的线程,来接收解码后的图像。如果只在一个线程中的话,最后得到的是无效数据。API介绍接收码流,停止接收码流接口// 原型hi_s32 hi_mpi_vdec_star...
这是媒体数据处理的第二篇博客,关于JPEG解码
- 流程图
注意此图有乾坤,我们之前接触到的不管是媒体数据处理V1还是v2的其它功能接口,都是可以在单线程与多线程之间自由选择的,而仔细看这幅图,标明用户需要重新起一个新的线程,来接收解码后的图像。如果只在一个线程中的话,最后得到的是无效数据。
- API介绍
- 接收码流,停止接收码流接口
// 原型
hi_s32 hi_mpi_vdec_start_recv_stream(hi_vdec_chn chn)
hi_s32 hi_mpi_vdec_stop_recv_stream(hi_vdec_chn chn)
参数
hi_vdec_chn chn:在昇腾710 AI处理器上,该参数的取值范围:[0, 256),通道总数最多256.
- 发送解码后的数据接口
// 原型
hi_s32 hi_mpi_vdec_send_stream(hi_vdec_chn chn, const hi_vdec_stream *stream, hi_vdec_pic_info *vdec_pic_info, hi_s32 milli_sec)
// 参数
hi_vdec_stream *stream :输入码流信息的指针,该结构体内的addr参数配置的地址为Device上的内存地址。
typedef struct {
hi_bool end_of_frame;当前帧是否结束(此值目前暂无效)
hi_bool end_of_stream;是否发完所有码流(发送有效帧与结束帧的时候注意)
hi_bool need_display;当前帧输出是否显示(是否保存到输出内存中)0不保存,1保存
hi_u64 pts;码流包的时间戳,以us为单位。仅按帧发送时有效等于码流包中的时间戳,按流发送时,解码图像的时间戳等于0
hi_u64 private_data;私有数据。预留参数
hi_u32 len;码流包的长度,以Byte为单位
hi_u8 *ATTRIBUTE addr;码流包的地址
} hi_vdec_stream;
hi_vdec_pic_info *vdec_pic_info:输出图片信息的指针
typedef struct {
hi_u32 width; // 图像原始宽度
hi_u32 height; // 图像原始高度
hi_u32 width_stride; // 图像对齐宽度
hi_u32 height_stride; // 图像对齐高度
hi_pixel_format pixel_format; // 图像像素格式
hi_u64 vir_addr; // 解码输出数据在内存中的起始地址
hi_u32 buffer_size; // 宽高对齐后数据在内存中的大小
hi_s16 offset_top; // 图像顶部剪裁宽度。(用于JPEG区域解码,当前不支持)
hi_s16 offset_bottom; // 图像底部剪裁宽度。(用于JPEG区域解码,当前不支持)
hi_s16 offset_left; // 图像左侧剪裁宽度。(用于JPEG区域解码,当前不支持)
hi_s16 offset_right; // 图像右侧剪裁宽度。(用于JPEG区域解码,当前不支持)
}hi_vdec_pic_info;
- 接收解码的数据接口(JPEGD图像解码秩只需关注这些有注释的参数即可其它参数或者不适用与JPEG解码或者目前是预留参数,内部没有进行处理)
// 原型
hi_s32 hi_mpi_vdec_get_frame(hi_vdec_chn chn, hi_video_frame_info *frame_info, hi_vdec_supplement_info *supplement, hi_vdec_stream *stream, hi_s32 milli_sec)
// 参数
hi_video_frame_info *frame_info:解码后的图像帧信息结构体。
typedef struct {
hi_video_frame v_frame; 真正存放解码后图像帧的结构体。
hi_u32 pool_id;
hi_mod_id mod_id;
} hi_video_frame_info;
typedef struct {
hi_u32 width; // 图像原始宽度
hi_u32 height; // 图像原始高度
hi_video_field field;
hi_pixel_format pixel_format; // 视频图像像素格式
hi_video_format video_format;
hi_compress_mode compress_mode;
hi_dynamic_range dynamic_range;
hi_color_gamut color_gamut;
hi_u32 header_stride[HI_MAX_COLOR_COMPONENT];
hi_u32 width_stride[HI_MAX_COLOR_COMPONENT]; // 图像对齐宽度
hi_u32 height_stride[HI_MAX_COLOR_COMPONENT]; // 图像对齐高度
hi_u64 header_phys_addr[HI_MAX_COLOR_COMPONENT];
hi_u64 phys_addr[HI_MAX_COLOR_COMPONENT];
hi_void* ATTRIBUTE header_virt_addr[HI_MAX_COLOR_COMPONENT];
hi_void* ATTRIBUTE virt_addr[HI_MAX_COLOR_COMPONENT]; 图像在Device内存中的起始虚拟地址.
hi_u32 time_ref;
hi_u64 pts; // 图像时间戳。
hi_u64 user_data[HI_MAX_USER_DATA_NUM];
hi_u32 frame_flag;
hi_video_supplement supplement;
} hi_video_frame;
一些关于媒体数据处理组件之间串联的理解
真实编程的场景中,不大可能只用一个组件,有可能面临组件串联的情况。例如
JPEG图像解码==》缩放、裁剪、抠图==》送入模型==》编码保存
视频解码==》缩放、裁剪、抠图==》送入模型==》编码保存
所以内存复用在这个过程中就显得尤为的重要,虽然可以把内容先保存到硬盘上然后再次读取,但是显然效率低下。
所以关于内存复用你需要了解以下几件事:
-
我们等待处理的图像数据,与我们原本存放在硬盘上的数据是完全相同的吗?
答案是不一定!!
上面一幅图已经足够解释为什么不一定,因为有些图像的宽高刚好符合对齐的要求,因此与源数据一致,一旦不符合就会产生无效的绿边填充成符合对其要求的数据,这也是为什么有时我们暴力保存内存中的数据会在右边下边有绿边的存在。 -
不同组件的输入与输出宽高对齐要求都不一样,难免会遇到不兼容的情况,那我需要怎么填写对其的宽和高呢?
答案是与前一个组件的对齐要求为准
大毛老师关于媒体数据处理的内存复用的解析
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)