企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
# 2.2 数据结构定义 ~~~ // 库包含编解码器能力定义 #define MEDIACODEC_CAPABILITY_AUDIOENCODEC 0x00000001 ///< 音频编码器 #define MEDIACODEC_CAPABILITY_AUDIODECODEC 0x00000002 ///< 音频解码器 #define MEDIACODEC_CAPABILITY_VIDEOENCODEC 0x00000004 ///< 视频编码器 #define MEDIACODEC_CAPABILITY_VIDEODECODEC 0x00000008 ///< 视频解码器 #define MEDIACODEC_CAPABILITY_YUV420SPINPUT 0x00000100 ///< 视频编码器支持YUV420SP 数据输入 #define MEDIACODEC_CAPABILITY_YUV420SPOUTPUT 0x00000200 ///< 视频解码器输出数据为 YUV420SP #define MEDIACODEC_CAPABILITY_DIRECTRENDER 0x00000400 ///< 支持直接视频显示,硬件渲染 // 功能标志定义 #define MEDIACODEC_FLAGS_KEYFRAME 0x00000001 ///< 关键帧标志 #define MEDIACODEC_FLAGS_WANTSPSPPS 0x00000002 ///< 上层应用处理 SPS、PPS 标志, 视频编码使用 #define MEDIACODEC_FLAGS_USEARMV6 0x00000100 ///< 强制使用 ARMv6 指令集 #define MEDIACODEC_FLAGS_NEEDREINIT 0x00000200 ///< 需要重新初始化 Codec #define MEDIACODEC_MAXCODECNAME 50 // 编解码器 ID 定义 enum MEDIA_CODEC_ID { MEDIA_CODEC_ID_NONE = 0, /* video codecs */ MEDIA_CODEC_ID_H264, MEDIA_CODEC_ID_MJPEG, /* audio codecs */ MEDIA_CODEC_ID_AMR_NB = 10, MEDIA_CODEC_ID_AMR_WB, MEDIA_CODEC_ID_MP3, MEDIA_CODEC_ID_AAC, MEDIA_CODEC_ID_MP2, MEDIA_CODEC_ID_CELT, MEDIA_CODEC_ID_SPEEX, /* user define codecs*/ MEDIA_CODEC_ID_USERSTART = 100, ///< 用户自定义编解码器起始 ID }; // 音视频数据包结构 typedef struct MediaPacket { CHAR *lpData; DWORD dwSize; DWORD dwFlags; DWORD dwTimeStamp; }MediaPacket,*LPMediaPacket; // 编解码器上下文句柄结构 struct MediaCodecContext { DWORD cbSize; ///< 结构体大小 DWORD dwCodecId;///< 编解码器 ID DWORD dwFlags; ///< 相关标志 CHAR szCodecName[MEDIACODEC_MAXCODECNAME];///< 编解码器的名称 // 编解码器私有数据 void* lpPrivateData; ///< 私有数据指针 // 音频部分参数 DWORD dwChannels; ///< 音频通道数 DWORD dwSamplesPerSec; ///< 音频采样率 DWORD dwBitsPerSample; ///< 音频量化位数 DWORD dwFrameSize; ///< 音频编码器处理帧长 // 视频部分 DWORD dwWidth; ///< 视频宽度 DWORD dwHeight; ///< 视频高度 DWORD dwFrameRate; ///< 帧率 DWORD dwGopSize; ///< 关键帧间隔 AC_PIX_FMT PixFmt; ///< 视频帧格式 // 编码设置 DWORD dwBitrate; ///< 目标码率,单位:bps DWORD dwQuality; ///< 质量 DWORD dwPreset; ///< 预设参数 // 显示部分 void* lpGlobalContext; ///< 全局环境,Android 中为 JavaVM* void* lpSuface; ///< 显示表面句柄 DWORD reserved[20]; ///< 保留 ~~~ 音视频数据包结构(struct MediaPacket)是 AnyChat 内核与 CODEC 交换数据的基本结构,里面包含了数据域(lpData)、数据长度(dwSize)和标志域(dwFlags),所有数据域的内存均由 AnyChat 内核分配与管理(包括输入类型与输出类型),CODEC 不需要再分配,对于输出类型的数据包,CODEC 内部需要检查 AnyChat 内核分配的内存是否足够(通过 dwSize 来判定),否则可能导致数据越界,形成非法内存访问异常,当 CODEC 内部检查到 AnyChat 内核分配的输出内存大小不足时,需要返回出错代码。标志域需要根据实际情况进行设置,如当视频编码 CODEC 输出的数据是关键帧时,标志域需要设置“MEDIACODEC_FLAGS_KEYFRAME”标志。 编解码器上下文句柄结构(struct MediaCodecContext)是 AnyChat 内核与 CODEC 之间传递参数的重要数据结构,初始化 CODEC 之前,AnyChat 内核会先设置相关的变量(如视频类型 CODEC 的宽度、高度、码率等),初始化 CODEC 之后,CODEC 内部需要设置该结构的相关变量,将信息返回给 AnyChat 内核,如初始化音频编码 CODEC 之后,CODEC 需要设置 dwFrameSize 变量,便于 AnyChat 内核了解每次需要向 CODEC 提交多少数据进行编码,详细信息可参考后面的“音频 CODEC” 和“视频 CODEC”等相关章节的具体说明。 编解码器上下文句柄结构(struct MediaCodecContext)中的“lpPrivateData”非常重要,可用于保存编解码器内部的状态参数,通常在初始化时分配内存,并初始化相关的状态,然后在编码(解码)的过程中使用,最后在关闭时释放内存, 分配内存、释放内存均在 CODEC 内部完成,“lpPrivateData”只是起一个中间桥梁的作用,AnyChat 内核会保障 CODEC 调用(初始化、编解码、关闭)之间的互斥。