当前位置:网站首页>openh264解码数据流向分析
openh264解码数据流向分析
2022-07-05 19:34:00 【HUI的技術筆記】
openh264dec中finish_frame的逻辑和avviddec比起来比较简单,在handle_frame中,buffer先送给解码器解码(DecodeFrameNoDelay),然后调用gst_video_decoder_finish_frame将解码后的buffer发到downstream。
DecodeFrameNoDelay解码,返回yuvdata,完成后unmap input_buffer:
openh264dec->decoder->DecodeFrameNoDelay (map_info.data, map_info.size,
yuvdata, &dst_buf_info);
gst_buffer_unmap (frame->input_buffer, &map_info);
gst_video_frame_map的功能
gst_video_frame_map()将在GstVideoFrame结构中填入buffer的像素以及所需的各种视频信息。
gboolean
gst_video_frame_map (GstVideoFrame * frame, GstVideoInfo * info, GstBuffer * buffer, GstMapFlags flags)
使用@info和@buffer来填入到@frame,地址会被传给分配在堆栈中的#GstVideoFrame结构。
可以使用访问器宏访问,如:
GST_VIDEO_FRAME_COMP_DATA()
GST_VIDEO_FRAME_PLANE_DATA()
GST_VIDEO_FRAME_COMP_STRIDE()
GST_VIDEO_FRAME_PLANE_STRIDE()
这个功能的目的是使你能够很容易地获得视频像素,而不需要担心太多细节问题。
比如视频数据是被分配在一个连续的内存块中还是多个内存块(例如,对于每一个plane都有一个内存块),或者是否使用自定义strides和自定义plane偏移(由每个缓冲区上的GstVideoMeta记录)。
这个函数只是用正确的值填充#GstVideoFrame结构,使用访问器宏,可以很容易地访问数据。它还会为你映射底层的内存块。
gst_video_frame_map的使用从ffmpeg avviddec和openh264dec的实现也可以看到,能方便的把解码器解码的数据放到plane内存块中。
GstVideoFrame的定义
/** * GstVideoFrame: * @info: the #GstVideoInfo * @flags: #GstVideoFrameFlags for the frame * @buffer: the mapped GstBuffer's buffer * @meta: pointer to metadata if any * @id: id of the mapped frame. the id can for example be used to * identify the frame in case of multiview video. * @data: pointers to the plane data * @map: mappings of the planes * * A video frame obtained from gst_video_frame_map() */
struct _GstVideoFrame {
GstVideoInfo info;
GstVideoFrameFlags flags;
GstBuffer *buffer;
gpointer meta;
gint id;
gpointer data[GST_VIDEO_MAX_PLANES];
GstMapInfo map[GST_VIDEO_MAX_PLANES];
/*< private >*/
gpointer _gst_reserved[GST_PADDING];
};
gst_video_decoder_allocate_output_frame
辅助函数,为@decoder当前的#GstVideoCodecState分配一个缓冲区来容纳一个视频帧。子类应该已经配置了视频状态并设置了src pad caps。从openH264dec和avdec_h264中都可以看到,最后解码的数据要先allocate_output_frame,然后copy数据到这个里面,avviddec里面的处理需要看get_output_buffer函数的实现。
gst_video_decoder_finish_frame
在openh264dec中,通过gst_video_decoder_finish_frame将解码后的数据push到downstream,如果没有提供输出数据,frame被视为skipped。在任何情况下,frame都被视为finished和released。
gst_openh264dec_handle_frame
- 收到frame后先交给openh264dec解码->DecodeFrameNoDelay
- gst_video_frame_map:映射frame->output_buffer,将解码的yuvdata填进去。
- gst_video_decoder_set_output_state:在srcpad上创建新的codec state作为解码器的输出状态
- gst_video_decoder_finish_frame发送给downstream
因为output state部分配置的是I420,所以在进行数据copy的时候,是yuv依次copy:
// i = 0; Y plane
// i = 1; U plane
// i = 2; V plane
for (i = 0; i < 3; i++) {
p = GST_VIDEO_FRAME_COMP_DATA (&video_frame, i);
row_stride = GST_VIDEO_FRAME_COMP_STRIDE (&video_frame, i);
component_width = GST_VIDEO_FRAME_COMP_WIDTH (&video_frame, i);
component_height = GST_VIDEO_FRAME_COMP_HEIGHT (&video_frame, i);
src_width =
i <
1 ? dst_buf_info.UsrData.sSystemBuffer.
iStride[0] : dst_buf_info.UsrData.sSystemBuffer.iStride[1];
for (row = 0; row < component_height; row++) {
memcpy (p, yuvdata[i], component_width);
p += row_stride;
yuvdata[i] += src_width;
}
}
边栏推荐
- Fundamentals of shell programming (Chapter 9: loop)
- Tutoriel de téléchargement et d'installation du progiciel fuzor 2020
- MMO项目学习一:预热
- Debezium系列之:解析默认值字符集
- 四万字长文说operator new & operator delete
- Do you know several assertion methods commonly used by JMeter?
- MySQL中字段类型为longtext的值导出后显示二进制串方式
- Necessary skills for interview in large factories, 2022android will not die, I will not fall
- 面试官:Redis中集合数据类型的内部实现方式是什么?
- JAD installation, configuration and integration idea
猜你喜欢

JAD的安装、配置及集成IDEA

Ten years at sea: old and new relay, dark horse rising

MMO項目學習一:預熱
Django使用mysqlclient服务连接并写入数据库的操作过程

Millimeter wave radar human body sensor, intelligent perception of static presence, human presence detection application

redis集群模拟消息队列

通过POI追加数据到excel中小案例
![[OBS] qstring's UTF-8 Chinese conversion to blog printing UTF-8 char*](/img/cc/172684664a9115943d45b0646ef110.png)
[OBS] qstring's UTF-8 Chinese conversion to blog printing UTF-8 char*
安卓面试宝典,2022Android面试笔试总结

【FAQ】华为帐号服务报错 907135701的常见原因总结和解决方法
随机推荐
flume系列之:拦截器过滤数据
微波雷达感应模块技术,实时智能检测人体存在,静止微小动静感知
大厂面试必备技能,2022Android不死我不倒
Django uses mysqlclient service to connect and write to the database
Mysql如何对json数据进行查询及修改
什么是面上项目
MMO项目学习一:预热
毫米波雷达人体感应器,智能感知静止存在,人体存在检测应用
Postman core function analysis - parameterization and test report
Information / data
#夏日挑战赛#数据库学霸笔记,考试/面试快速复习~
Mariadb root用户及普通用户的密码 重置
Apprentissage du projet MMO I: préchauffage
Microwave radar induction module technology, real-time intelligent detection of human existence, static micro motion and static perception
Go语言学习教程(十六)
JMeter 常用的几种断言方法,你会了吗?
Fundamentals of machine learning (III) -- KNN / naive Bayes / cross validation / grid search
【硬核干货】数据分析哪家强?选Pandas还是选SQL
【C语言】字符串函数及模拟实现strlen&&strcpy&&strcat&&strcmp
安卓面试宝典,2022Android面试笔试总结