【H.264】H.264详解(二)—— H264视频码流解析示例源码

文章目录

    • 一、前言
    • 二、示例源码
      • 【1】目录结构
      • 【2】Makefile源码
      • 【3】h264parser.c源码
      • 【4】编译运行
      • 【5】源码下载地址

声明:此篇示例源码非原创,原作者雷霄骅。雷霄骅,中国传媒大学通信与信息系统专业博士生,在此向雷霄骅雷神致敬。
代码原文地址:视音频数据处理入门:H.264视频码流解析

一、前言

示例源码是一个H.264码流解析程序。该程序可以从H.264码流中分析得到它的基本单元NALU,分离出NALU,然后再分析NALU的各个字段。

关于NALU的相关内容可参考文章【H.264】H.264详解(一)—— 一文看懂H.264协议

二、示例源码

【1】目录结构

project/
├── Makefile
├── h264parser.c
├── sintel.h264

【2】Makefile源码

app:h264parser.cgcc -o app h264parser.c
clean:rm -f app

【3】h264parser.c源码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>typedef enum {NALU_TYPE_SLICE    = 1,NALU_TYPE_DPA      = 2,NALU_TYPE_DPB      = 3,NALU_TYPE_DPC      = 4,NALU_TYPE_IDR      = 5,NALU_TYPE_SEI      = 6,NALU_TYPE_SPS      = 7,NALU_TYPE_PPS      = 8,NALU_TYPE_AUD      = 9,NALU_TYPE_EOSEQ    = 10,NALU_TYPE_EOSTREAM = 11,NALU_TYPE_FILL     = 12,
} NaluType;typedef enum {NALU_PRIORITY_DISPOSABLE = 0,NALU_PRIRITY_LOW         = 1,NALU_PRIORITY_HIGH       = 2,NALU_PRIORITY_HIGHEST    = 3
} NaluPriority;typedef struct{int startcodeprefix_len;      //! 4 for parameter sets and first slice in picture, 3 for everything else (suggested)unsigned len;                 //! Length of the NAL unit (Excluding the start code, which does not belong to the NALU)unsigned max_size;            //! Nal Unit Buffer sizeint forbidden_bit;            //! should be always FALSEint nal_reference_idc;        //! NALU_PRIORITY_xxxxint nal_unit_type;            //! NALU_TYPE_xxxx    char *buf;                    //! contains the first byte followed by the EBSP
} NALU_t;FILE *h264bitstream = NULL;                //!< the bit stream fileint info2=0, info3=0;static int FindStartCode2 (unsigned char *Buf){if(Buf[0]!=0 || Buf[1]!=0 || Buf[2] !=1) return 0; //0x000001?else return 1;
}static int FindStartCode3 (unsigned char *Buf){if(Buf[0]!=0 || Buf[1]!=0 || Buf[2] !=0 || Buf[3] !=1) return 0;//0x00000001?else return 1;
}int GetAnnexbNALU (NALU_t *nalu){int pos = 0;int StartCodeFound, rewind;unsigned char *Buf;if ((Buf = (unsigned char*)calloc (nalu->max_size , sizeof(char))) == NULL) printf ("GetAnnexbNALU: Could not allocate Buf memory\n");nalu->startcodeprefix_len=3;if (3 != fread (Buf, 1, 3, h264bitstream)){free(Buf);return 0;}info2 = FindStartCode2 (Buf);if(info2 != 1) {if(1 != fread(Buf+3, 1, 1, h264bitstream)){free(Buf);return 0;}info3 = FindStartCode3 (Buf);if (info3 != 1){ free(Buf);return -1;}else {pos = 4;nalu->startcodeprefix_len = 4;}}else{nalu->startcodeprefix_len = 3;pos = 3;}StartCodeFound = 0;info2 = 0;info3 = 0;while (!StartCodeFound){if (feof (h264bitstream)){nalu->len = (pos-1)-nalu->startcodeprefix_len;memcpy (nalu->buf, &Buf[nalu->startcodeprefix_len], nalu->len);     nalu->forbidden_bit = nalu->buf[0] & 0x80; //1 bitnalu->nal_reference_idc = nalu->buf[0] & 0x60; // 2 bitnalu->nal_unit_type = (nalu->buf[0]) & 0x1f;// 5 bitfree(Buf);return pos-1;}Buf[pos++] = fgetc (h264bitstream);info3 = FindStartCode3(&Buf[pos-4]);if(info3 != 1)info2 = FindStartCode2(&Buf[pos-3]);StartCodeFound = (info2 == 1 || info3 == 1);}// Here, we have found another start code (and read length of startcode bytes more than we should// have.  Hence, go back in the filerewind = (info3 == 1)? -4 : -3;if (0 != fseek (h264bitstream, rewind, SEEK_CUR)){free(Buf);printf("GetAnnexbNALU: Cannot fseek in the bit stream file");}// Here the Start code, the complete NALU, and the next start code is in the Buf.  // The size of Buf is pos, pos+rewind are the number of bytes excluding the next// start code, and (pos+rewind)-startcodeprefix_len is the size of the NALU excluding the start codenalu->len = (pos+rewind)-nalu->startcodeprefix_len;memcpy (nalu->buf, &Buf[nalu->startcodeprefix_len], nalu->len);//nalu->forbidden_bit = nalu->buf[0] & 0x80; //1 bitnalu->nal_reference_idc = nalu->buf[0] & 0x60; // 2 bitnalu->nal_unit_type = (nalu->buf[0]) & 0x1f;// 5 bitfree(Buf);return (pos+rewind);
}/*** Analysis H.264 Bitstream* @param url    Location of input H.264 bitstream file.*/
int simplest_h264_parser(char *url){NALU_t *n = NULL;int buffersize=100000;//FILE *myout=fopen("output_log.txt","wb+");FILE *myout=stdout;h264bitstream=fopen(url, "rb+");if (h264bitstream==NULL){printf("Open file error\n");return 0;}n = (NALU_t*)calloc (1, sizeof(NALU_t));if (n == NULL){printf("Alloc NALU Error\n");return 0;}n->max_size=buffersize;n->buf = (char*)calloc (buffersize, sizeof(char));if (n->buf == NULL){free (n);printf ("AllocNALU: n->buf");return 0;}int data_offset=0;int nal_num=0;printf("-----+-------- NALU Table ------+---------+\n");printf(" NUM |   POS   |   IDC  |  TYPE |   LEN   |\n");printf("-----+---------+--------+-------+---------+\n");while(!feof(h264bitstream)){int data_lenth;data_lenth=GetAnnexbNALU(n);char type_str[20]={0};switch(n->nal_unit_type){case NALU_TYPE_SLICE:sprintf(type_str,"SLICE");break;case NALU_TYPE_DPA:sprintf(type_str,"DPA");break;case NALU_TYPE_DPB:sprintf(type_str,"DPB");break;case NALU_TYPE_DPC:sprintf(type_str,"DPC");break;case NALU_TYPE_IDR:sprintf(type_str,"IDR");break;case NALU_TYPE_SEI:sprintf(type_str,"SEI");break;case NALU_TYPE_SPS:sprintf(type_str,"SPS");break;case NALU_TYPE_PPS:sprintf(type_str,"PPS");break;case NALU_TYPE_AUD:sprintf(type_str,"AUD");break;case NALU_TYPE_EOSEQ:sprintf(type_str,"EOSEQ");break;case NALU_TYPE_EOSTREAM:sprintf(type_str,"EOSTREAM");break;case NALU_TYPE_FILL:sprintf(type_str,"FILL");break;}char idc_str[20]={0};switch(n->nal_reference_idc>>5){case NALU_PRIORITY_DISPOSABLE:sprintf(idc_str,"DISPOS");break;case NALU_PRIRITY_LOW:sprintf(idc_str,"LOW");break;case NALU_PRIORITY_HIGH:sprintf(idc_str,"HIGH");break;case NALU_PRIORITY_HIGHEST:sprintf(idc_str,"HIGHEST");break;}fprintf(myout,"%5d| %8d| %7s| %6s| %8d|\n",nal_num,data_offset,idc_str,type_str,n->len);data_offset=data_offset+data_lenth;nal_num++;}//Freeif (n){if (n->buf){free(n->buf);n->buf=NULL;}free (n);}return 0;
}int main(int argc, char* argv[]){simplest_h264_parser("sintel.h264");return 0;
}

【4】编译运行

在这里插入图片描述

【5】源码下载地址

H.264详解(二)- H264视频码流解析示例源码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/384512.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL客户端命令一节将.sql文件导入MySQL

MySql客户端命令 直接输入SQL语句 使用MySQL客户端连接到服务器之后&#xff0c;可以发送SQL语句到服务器执行&#xff0c;并且以&#xff1b;和\g, \G作为结束不同的结束方式显示内容有所不同** TIPS: ;和\g结尾以表格的形式显示结果\G以行的形式显示结果 在连接到服务器之后…

FineBI连接MySQL5.7

一、在FineBI系统管理中&#xff0c;点击【新建数据库连接】 选择MySQL数据库 配置数据库连接&#xff0c;如下&#xff0c;其中数据库名称就是需要连接的目标数据库

5.CSS学习(浮动)

浮动&#xff08;float&#xff09; 是一种传统的网页布局方式&#xff0c;通过浮动&#xff0c;可以使元素脱离文档流的控制&#xff0c;使其横向排列。 其编写在CSS样式中。 float:none(默认值) 元素不浮动。 float:left 设置的元素在其包含…

Web3 职场新手指南:从技能到素养,求职者如何脱颖而出?

随着 2024 年步入下半年&#xff0c;Web3 行业正在经历一系列技术革新。通过改进的跨链交互机制和兼容性&#xff0c;逐步消除市场碎片化的问题。技术的进步为开发者和用户都打开了新的前景。然而&#xff0c;复杂的技术和快速变化的市场环境也让许多新人望而却步。求职者如何找…

Unity 之 【Android Unity 共享纹理】之 Android 共享图片给 Unity 显示

Unity 之 【Android Unity 共享纹理】之 Android 共享图片给 Unity 显示 目录 Unity 之 【Android Unity 共享纹理】之 Android 共享图片给 Unity 显示 一、简单介绍 二、共享纹理 1、共享纹理的原理 2、共享纹理涉及到的关键知识点 3、什么可以实现共享 不能实现共享…

LeetCode 2844.生成特殊数字的最少操作(哈希表 + 贪心)

给你一个下标从 0 开始的字符串 num &#xff0c;表示一个非负整数。 在一次操作中&#xff0c;您可以选择 num 的任意一位数字并将其删除。请注意&#xff0c;如果你删除 num 中的所有数字&#xff0c;则 num 变为 0。 返回最少需要多少次操作可以使 num 变成特殊数字。 如…

Web漏洞扫描工具(AWVS、Goby)

一、背景 想针对自己项目或者小公司的Web安全做相关扫描&#xff0c;自己做漏洞进行自查工作&#xff0c;能够减少自身系统的安全风险&#xff0c;提高系统的安全性。但是没有找到一些开源性质的、扫描质量比较高的相关工具&#xff0c;使用安全公司的专业产品价格又承受不起。…

MySQL_JDBC

目录 一、JDBC常用的接口和类 1.1 数据库连接 Connection 1.2 Statement 对象 二、JDBC的使用 总结 【Java 的数据库编程】 JDBC 即 Java Database Connectivity (Java数据库连接)&#xff0c;是一种用于执行 SQL 语句的 Java API。这个 API 由 java.sql.*,javax.sql.* …

kettle从入门到精通 第八十一课 ETL之kettle kettle中的json对象字段写入postgresql中的json字段正确姿势

1、上一节可讲解了如何将json数据写入pg数据库表中的json字段&#xff0c;虽然实现了效果&#xff0c;但若客户继续使用表输出步骤则仍然无法解决问题。 正确的的解决方式是设置数据库连接参数stringtypeunspecified 2、stringtypeunspecified 参数的作用&#xff1a; 当设置…

ERROR: Cannot find command ‘git’- do you have ‘git’ installed and in your PATH?

ERROR: Cannot find command ‘git’- do you have ‘git’ installed and in your PATH? 目录 ERROR: Cannot find command ‘git’- do you have ‘git’ installed and in your PATH? 【常见模块错误】 【解决方案】 欢迎来到英杰社区https://bbs.csdn.net/topics/61780…

Java开发新趋势!MyEclipse v2024.1全新首发——支持AI编码协助

在MyEclipse 2024中&#xff0c;通过Copilot集成提供的AI编码协助&#xff0c;让开发者的生产力提高了近10倍&#xff1b;同时支持Java 22&#xff0c;并部署到最新版本的应用服务器(如WildFly和Payara)&#xff1b;拥有更高性能的Spring工具支持更流畅的编码体验&#xff0c;而…

新增ClamAV病毒扫描功能、支持Java和Go运行环境,1Panel开源面板v1.10.12版本发布

2024年7月19日&#xff0c;现代化、开源的Linux服务器运维管理面板1Panel正式发布了v1.10.12版本。 在这一版本中&#xff0c;1Panel新增了多项实用功能。社区版方面&#xff0c;1Panel新增ClamAV病毒扫描功能、支持Java和Go运行环境&#xff0c;同时1Panel还新增了文件编辑器…

耳机、音响UWB传输数据模组,飞睿智能低延迟、高速率超宽带uwb模块技术音频应用

在数字化浪潮席卷全球的今天&#xff0c;无线通信技术日新月异&#xff0c;其中超宽带&#xff08;Ultra-Wideband&#xff0c;简称UWB&#xff09;技术以其独特的优势&#xff0c;正逐步成为无线传输领域的新星。本文将深入探讨飞睿智能UWB传输数据模组在音频应用中的创新应用…

Xilinx Ultrascale+ FPGA 驱动MIPI DSI屏显示源码工程

作者&#xff1a;Hello&#xff0c;Panda 大家早上好&#xff0c;中午好&#xff0c;下午好&#xff0c;我是熊猫君。 曾记否&#xff0c;之前熊猫家发了一篇博文《分享一下使用Xilinx FPGA驱动MIPI DSI屏的心路历程》&#xff0c;此文发布以后&#xff0c;后台收到了不少朋友…

FPGA与ASIC:深入解析芯片设计的双子星

前言 在半导体世界里&#xff0c;FPGA&#xff08;Field-Programmable Gate Array&#xff0c;现场可编程门阵列&#xff09;与ASIC&#xff08;Application-Specific Integrated Circuit&#xff0c;专用集成电路&#xff09;是两种截然不同的芯片设计策略&#xff0c;各自在…

【Linux】虚拟机安装 openEuler 24.03 X86_64

目录 一、概述 1.1 openEuler 覆盖全场景的创新平台 1.2 系统框架 1.3 平台框架 二、安装详细步骤 一、概述 1.1 openEuler 覆盖全场景的创新平台 openEuler 已支持 x86、Arm、SW64、RISC-V、LoongArch 多处理器架构&#xff0c;逐步扩展 PowerPC 等更多芯片架构支持&…

C++编译jsoncpp库

下载https://github.com/hailong0715/jsoncpp/tree/master windows编译工程 jsoncpp-master\makefiles\vs71 1.msvcprtd.lib(MSVCP140D.dll) : error LNK2005 解决办法&#xff1a; (1).工程(Project)->属性(Properties)->配置属性(Configuration Properties)->c/c-…

在invidia jetpack4.5.1上运行c++版yolov8(tensorRT)

心路历程&#xff08;可略过&#xff09; 为了能在arm64上跑通yolov8&#xff0c;我试过很多很多代码&#xff0c;太多对库版本的要求太高了&#xff1b; 比如说有一个是需要依赖onnx库的&#xff0c;&#xff08;https://github.com/UNeedCryDear/yolov8-opencv-onnxruntime-…

GraphHopper路径规划引擎-可执行jar版

本文是使用开源的graphhopper路径规划引擎&#xff0c;可执行jar包的方式启动引擎服务&#xff0c;按照官方地址&#xff0c;进行实践记录。 Graphhopper后台服务启动&#xff08;可执行 JAR 文件&#xff09; 特别说明&#xff1a;当前graphhopper的版本是9.x&#xff0c;运…

AI有关的学习和python

一、基本概念 AIGC&#xff08;AI Generated content AI 生成内容&#xff09; AI生成的文本、代码、图片、音频、视频。都可以成为AIGC。 Generative AI&#xff08;生成式AI&#xff09;所生成的内容就是AIGC AI指代计算机人工智能&#xff0c;模仿人类的智能从而解决问题…