当前位置:网站首页>Analysis of openh264 decoded data flow
Analysis of openh264 decoded data flow
2022-07-05 19:40:00 【Hui's technical notes】
openh264dec in finish_frame Logic and avviddec It's simpler , stay handle_frame in ,buffer First send it to the decoder for decoding (DecodeFrameNoDelay
), And then call gst_video_decoder_finish_frame
Will decode the buffer Send to downstream.
DecodeFrameNoDelay decode , return yuvdata, After completion 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 The function of
gst_video_frame_map() Will be in GstVideoFrame Fill in the structure buffer Pixels and all kinds of video information required .
gboolean
gst_video_frame_map (GstVideoFrame * frame, GstVideoInfo * info, GstBuffer * buffer, GstMapFlags flags)
Use @info and @buffer To fill in @frame, The address will be passed to the #GstVideoFrame structure .
You can use the accessor macro to access , Such as :
GST_VIDEO_FRAME_COMP_DATA()
GST_VIDEO_FRAME_PLANE_DATA()
GST_VIDEO_FRAME_COMP_STRIDE()
GST_VIDEO_FRAME_PLANE_STRIDE()
The purpose of this function is to make it easy for you to get video pixels , Don't worry about too many details .
For example, is video data allocated in a continuous memory block or multiple memory blocks ( for example , For each of these plane There is a memory block ), Or whether to use customization strides And customization plane The offset ( By GstVideoMeta Record ).
This function just fills in with the correct value #GstVideoFrame structure
, Use accessor macros , Data can be easily accessed . It also maps the underlying memory blocks for you .
gst_video_frame_map Use of from ffmpeg avviddec and openh264dec You can also see the implementation of , It is convenient to put the data decoded by the decoder into plane In the memory block .
GstVideoFrame The definition of
/** * 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
Auxiliary function , by @decoder Current #GstVideoCodecState Allocate a buffer to hold a video frame . The subclass should have configured the video state and set src pad caps. from openH264dec and avdec_h264 You can see , Finally, the decoded data must first allocate_output_frame, then copy Data into this ,avviddec The processing inside needs to see get_output_buffer Implementation of function .
gst_video_decoder_finish_frame
stay openh264dec in , adopt gst_video_decoder_finish_frame
Decoded data push To downstream, If no output data is provided ,frame Be regarded as skipped. In any case ,frame Are considered finished and released.
gst_openh264dec_handle_frame
- received frame Then hand it over to openh264dec decode ->DecodeFrameNoDelay
- gst_video_frame_map: mapping frame->output_buffer, What will be decoded yuvdata Fill in .
- gst_video_decoder_set_output_state: stay srcpad Create a new codec state As the output state of the decoder
- gst_video_decoder_finish_frame Send to downstream
because output state Part of the configuration is I420, So we are doing data copy When , yes yuv successively 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;
}
}
边栏推荐
- 司空见惯 - 英雄扫雷鼠
- 不愧是大佬,字节大牛耗时八个月又一力作
- PHP uses ueditor to upload pictures and add watermarks
- Debezium系列之:postgresql从偏移量加载正确的最后一次提交 LSN
- Tutoriel de téléchargement et d'installation du progiciel fuzor 2020
- 安信证券在网上开户安全吗?
- Django uses mysqlclient service to connect and write to the database
- 面试官:Redis中集合数据类型的内部实现方式是什么?
- PG基础篇--逻辑结构管理(用户及权限管理)
- Pandora IOT development board learning (HAL Library) - Experiment 8 timer interrupt experiment (learning notes)
猜你喜欢
[Collection - industry solutions] how to build a high-performance data acceleration and data editing platform
What are the reliable domestic low code development platforms?
UWB ultra wideband positioning technology, real-time centimeter level high-precision positioning application, ultra wideband transmission technology
Reinforcement learning - learning notes 4 | actor critical
How to apply smart contracts more wisely in 2022?
毫米波雷达人体感应器,智能感知静止存在,人体存在检测应用
【AI 框架基础技术】自动求导机制 (Autograd)
如何在2022年更明智地应用智能合约?
Decision tree and random forest
Bitcoinwin (BCW)受邀参加Hanoi Traders Fair 2022
随机推荐
What is the core value of testing?
国海证券在网上开户安全吗?
Worthy of being a boss, byte Daniel spent eight months on another masterpiece
城链科技数字化创新战略峰会圆满召开
Fundamentals of machine learning (III) -- KNN / naive Bayes / cross validation / grid search
信息/数据
Fuzor 2020软件安装包下载及安装教程
Mariadb root用户及普通用户的密码 重置
完爆面试官,一线互联网企业高级Android工程师面试题大全
Vagrant2.2.6 supports virtualbox6.1
S7-200SMART利用V90 MODBUS通信控制库控制V90伺服的具体方法和步骤
多分支结构
使用 RepositoryProvider简化父子组件的传值
众昂矿业:2022年全球萤石行业市场供给现状分析
不愧是大佬,字节大牛耗时八个月又一力作
力扣 1200. 最小绝对差
How about testing outsourcing companies?
Fuzor 2020 software installation package download and installation tutorial
Is it safe for Guohai Securities to open an account online?
MySql中的longtext字段的返回问题及解决