Peergine 扩展设备输入输出C接口说明 v1.9

1. 概述

Peergine中间件在常用的操作系统平台上,都支持了视频采集和压缩功能。视频采集通常调用操作系统的标准API,压缩使用软件编码。

但在一些专用的设备上,视频采集API专有,不标准。而且,设备上可能支持硬件压缩,编解码器的API也是专有。这使得Peergine不能应用在更多专用的设备上,因而,Peergine中间件开放一套视频I/O接口,让应用程序可以在中间件外部采集视频并且进行压缩编码,然后再输入到Peergine中间件里面来。这样一来,Peergine中间件的系统环境适应性就有了很大的增强。本文所述的扩展输入输出接口在系统中的位置如下图所示:

层次结构图

应用

SDK封装层

Peergine中间件

扩展输入输出接口

设备系统和硬件

扩展输入输出接口分为5套接口,分别是:

1)视频输入接口,在头文件pgLibDevVideoIn.h中声明。

2)视频输出接口,在头文件pgLibDevVideoOut.h中声明。

3)音频输入接口,在头文件pgLibDevAudioIn.h中声明。

4)音频输出接口,在头文件pgLibDevAudioOut.h中声明。

5)音频转换接口,在头文件pgLibDevAudioConvert.h中声明。

2. 视频输入API接口(pgLibDevVideoIn.h)

1)说明

从Peergine中间件的1.42.0版本开始,增加了内置的H.264和H.265输入组帧功能,应用程序可以在pfnVideoInOpen()回调函数里面,调用pgDevVideoInSetParam()函数设置

PG_DEV_VIDEO_IN_PARAM_ASSEM_FRAME参数项,启用或关闭内置输入组帧功能。

2)常量:

PG_DEV_VIDEO_IN_FMT_E:视频输入格式

typedef enum tagPG_DEV_VIDEO_IN_FMT_E {

PG_DEV_VIDEO_IN_FMT_RGB24, // 视频帧像素格式为RGB24

PG_DEV_VIDEO_IN_FMT_YUV422SP, // 视频帧像素格式为YUV422SP

PG_DEV_VIDEO_IN_FMT_YUV420SP, // 视频帧像素格式为YUV420SP

PG_DEV_VIDEO_IN_FMT_YUYV, // 视频帧像素格式为YUYV

PG_DEV_VIDEO_IN_FMT_YV12, // 视频帧像素格式为YV12

PG_DEV_VIDEO_IN_FMT_MJPEG, // 视频帧压缩编码格式为JPEG A

PG_DEV_VIDEO_IN_FMT_VP8, // 视频帧压缩编码格式为VP8

PG_DEV_VIDEO_IN_FMT_H264, // 视频帧压缩编码格式为H.264

PG_DEV_VIDEO_IN_FMT_H265, // 视频帧压缩编码格式为H.265

PG_DEV_VIDEO_IN_FMT_I420, // 视频帧像素格式为I420

PG_DEV_VIDEO_IN_FMT_BUTT

} PG_DEV_VIDEO_IN_FMT_E;

PG_DEV_VIDEO_IN_FLAG_E:视频输入标志位

typedef enum tagPG_DEV_VIDEO_IN_FLAG_E {

PG_DEV_VIDEO_IN_FLAG_KEY_FRAME = 0x0001, // 当前输入的视频帧为关键帧

} PG_DEV_VIDEO_IN_FLAG_E;

PG_DEV_VIDEO_IN_CTRL_E:视频输入控制命令

typedef enum tagPG_DEV_VIDEO_IN_CTRL_E {

PG_DEV_VIDEO_IN_CTRL_PULL_KEY_FRAME, // 立即输入一个关键帧

PG_DEV_VIDEO_IN_CTRL_BUTT

} PG_DEV_VIDEO_IN_CTRL_E;

PG_DEV_VIDEO_IN_PARAM_E:视频输入参数的条目

typedef enum tagPG_DEV_VIDEO_IN_PARAM_E {

PG_DEV_VIDEO_IN_PARAM_NO, // 摄像头编号参数

PG_DEV_VIDEO_IN_PARAM_FACING, // 摄像头方向(前置/后置)

PG_DEV_VIDEO_IN_PARAM_ROTATE, // 摄像头采集的视频角度

PG_DEV_VIDEO_IN_PARAM_IMG_ROTATE, // 摄像头采集得到的视频图像数据的存储角度

PG_DEV_VIDEO_IN_PARAM_ASSEM_FRAME, // 启用/禁用中间件内部的视频组帧功能

PG_DEV_VIDEO_IN_PARAM_BUTT

} PG_DEV_VIDEO_IN_PARAM_E;

参数条目的说明:

PG_DEV_VIDEO_IN_PARAM_NO:摄像头编号参数

调用pgDevVideoInSetParam()设置最后选用的摄像头的编号。从uValue参数传入摄像头的编号,uValue的有效范围为0~65534(摄像头编号的具体数值依赖各个操作系统上的摄像头接口定义)。

PG_DEV_VIDEO_IN_PARAM_FACING:摄像头方向(前置/后置)

调用pgDevVideoInSetParam()设置摄像头方向(前置还是后置)。从uValue参数传入方向值:1为前置,0为后置。

PG_DEV_VIDEO_IN_PARAM_ROTATE:摄像头采集的视频角度

调用pgDevVideoInGetParam()获取摄像头的采集视频角度,然后按照这个角度打开摄像头。pgDevVideoInGetParam()的返回值为摄像头的采集角度,有效值为0、90、180、270,默认值为0。

PG_DEV_VIDEO_IN_PARAM_IMG_ROTATE:摄像头采集得到的视频图像数据的存储角度

调用pgDevVideoInSetParam()设置摄像头采集端的数据的旋转角度。从uValue参数传入角度值,有效值为有效值为0、90、180、270,默认值为0。

PG_DEV_VIDEO_IN_PARAM_ASSEM_FRAME:启用/禁用中间件内部的视频组帧功能

调用pgDevVideoInSetParam()设置是否启用Peergine中间件内置的H264、H265组帧功能。uValue的值,1为启用内置组帧、0为禁用(默认值)。

3)结构体:

PG_DEV_VIDEO_IN_CALLBACK_S:视频输入回调接口结构

typedef struct tagPG_DEV_VIDEO_IN_CALLBACK_S {

// 打开视频采集设备,开始视频采集

int (*pfnVideoInOpen)(unsigned int uDevNO, unsigned int uPixBytes,

unsigned int uWidth, unsigned int uHeight, unsigned int uBitRate,

unsigned int uFrmRate, unsigned int uKeyFrmRate);

// 停止视频采集,关闭视频采集设备

void (*pfnVideoInClose)(int iDevID);

// 发送控制命令给视频采集设备

void (*pfnVideoInCtrl)(int iDevID, unsigned int uCtrl, unsigned int uParam);

} PG_DEV_VIDEO_IN_CALLBACK_S;

4)API函数:

pgDevVideoInSetCallback:设置视频输入回调接口

/**

* 描述:设备回调接口

* 阻塞方式:非阻塞,立即返回。

* lpstCallback:[IN] 回调接口结构指针

*/

void pgDevVideoInSetCallback(const PG_DEV_VIDEO_IN_CALLBACK_S* lpstCallback);

pgDevVideoInCaptureProc:视频帧数据输入

/**

* 描述:输入视频帧数据到 Peergine中间件中

* 注意事项:

* 1)每次必须输入一个完整的视频帧。不能分片,也不能一次输入多帧。

* 2)如果输入的视频格式是H264或者H265,则必须周期性地输入I帧。

* 3)如果输入的视频格式是H264或者H265,则输入的每个I帧必须附带SPS头。

* 阻塞方式:阻塞,视频帧数据缓冲到 Peergine中间件队列后返回

* iDevID: [IN] 设备ID。回调函数’pfnVideoInOpen’的返回值

* lpData: [IN] 视频帧数据的缓冲区指针

* uDataSize: [IN] 视频帧数据的长度(字节)

* uFormat: [IN] 视频帧的格式,见枚举 ‘PG_DEV_VIDEO_IN_FMT_E’

* uFlag: [IN] 标志位,见枚举 ‘tagPG_DEV_VIDEO_IN_FLAG_E’

*/

void pgDevVideoInCaptureProc(int iDevID, const void* lpData,

unsigned int uDataSize, unsigned int uFormat, unsigned int uFlag);

pgDevVideoInSetParam:设置视频输入参数

/**

* 设置与 ‘uDevNO’ 相关联的输入参数到SDK

* 注意: 本函数只能在回调函数’pfnVideoInOpen’的内部调用

* uDevNO: [in] 回调函数’pfnVideoInOpen’的 ‘uDevNO’ 参数

* uItem: [in] 输入参数的条目id,见枚举 ‘PG_DEV_VIDEO_IN_PARAM_E’

* uValue: [in] 设置的参数的值

* 返回值: <0: 失败,>=0: 成功

*/

int pgDevVideoInSetParam(unsigned int uDevNO, unsigned int uItem, unsigned int uValue);

pgDevVideoInGetParam:获取视频输入参数

/**

* 从SDK获取与 ‘uDevNO’ 相关联的输入参数

* 注意: 本函数只能在回调函数’pfnVideoInOpen’的内部调用

* uDevNO: [in] 回调函数’pfnVideoInOpen’的 ‘uDevNO’ 参数

* uItem: [in] 输入参数的条目id,见枚举 ‘PG_DEV_VIDEO_IN_PARAM_E’

* 返回值: <0: 失败,>=0: 获取的参数值

*/

int pgDevVideoInGetParam(unsigned int uDevNO, unsigned int uItem);

5)回调函数:

pfnVideoInOpen:打开视频采集设备进行采集

/**

* 描述:打开视频采集设备进行采集。

* 注意:采集的视频图像的分辨率必须与传入的uWidth和uHeight参数一致。

* uDevNO: [IN] 视频采集设备的编号,Android系统为CameraInfo.facing的值(前置/后置)。

* uPixBytes: [IN] 像素的字节数,目前只支持3字节。

* uWidth: [IN] 视频的宽度(像素)

* uHeight: [IN] 视频的高度(像素)

* uBitRate: [IN] 视频的码率(可选)

* uFrmRate: [IN] 视频的帧率(可选)

* uKeyFrmRate:[IN] 关键帧率,每隔多少视频帧有1个关键帧

* 返回值:小于0失败,大于0返回设备ID。

*/

int (*pfnVideoInOpen)(unsigned int uDevNO, unsigned int uPixBytes,

unsigned int uWidth, unsigned int uHeight, unsigned int uBitRate,

unsigned int uFrmRate, unsigned int uKeyFrmRate);

pfnVideoInClose:关闭视频采集设备停止采集

/**

* 描述:关闭视频采集设备停止采集。

* iDevID:[IN] 视频采集设备的ID,也就是’ pfnVideoInOpen’回调函数的返回值。

*/

void (*pfnVideoInClose)(int iDevID);

pfnVideoInCtrl:接收到字符串数据

/**

* 描述:接收到字符串数据。

* iDevID: [IN] 视频采集设备的ID,也就是’pfnVideoInOpen’回调函数的返回值。

* uCtrl: [IN] 控制命令,参考枚举’PG_DEV_VIDEO_IN_CTRL_E’定义。

* uParam: [IN] 参数,未使用。

*/

void (*pfnVideoInCtrl)(int iDevID, unsigned int uCtrl, unsigned int uParam);

3. 视频输出API接口(pgLibDevVideoOut.h)

1)说明

从Peergine中间件的1.42.0版本开始,增加了获取视频流的帧率的功能,应用程序可以在pfnVideoOutOpen()回调函数里面,调用pgDevVideoOutGetParam()函数获取

PG_DEV_VIDEO_OUT_PARAM_FRAME_RATE参数项的值,就是当前视频流的帧率。

2)常量:

PG_DEV_VIDEO_OUT_FMT_E:视频输出格式

typedef enum tagPG_DEV_VIDEO_OUT_FMT_E {

PG_DEV_VIDEO_OUT_FMT_RGB24,

PG_DEV_VIDEO_OUT_FMT_MJPEG,

PG_DEV_VIDEO_OUT_FMT_VP8,

PG_DEV_VIDEO_OUT_FMT_H264,

PG_DEV_VIDEO_OUT_FMT_H265,

PG_DEV_VIDEO_OUT_FMT_I420,

PG_DEV_VIDEO_OUT_FMT_BUTT

} PG_DEV_VIDEO_OUT_FMT_E;

PG_DEV_VIDEO_OUT_FLAG_E:视频输出标志位

typedef enum tagPG_DEV_VIDEO_OUT_FLAG_E {

PG_DEV_VIDEO_OUT_FLAG_KEY_FRAME = 0x0001, // 图像为关键帧

} PG_DEV_VIDEO_OUT_FLAG_E;

PG_DEV_VIDEO_OUT_EVENT_E:视频输出事件

typedef enum tagPG_DEV_VIDEO_OUT_EVENT_E {

PG_DEV_VIDEO_OUT_EVENT_PAINT, // 强制重绘图像

} PG_DEV_VIDEO_OUT_EVENT_E;

PG_DEV_VIDEO_OUT_FILL_MODE_E:视频输出图像填充模式

typedef enum tagPG_DEV_VIDEO_OUT_FILL_MODE_E {

PG_DEV_VIDEO_OUT_FILL_MODE_DST_IN_SRC, // 等长宽比伸缩,填满目标区域,裁剪图像超出的部分。

PG_DEV_VIDEO_OUT_FILL_MODE_SRC_IN_DST, // 等长宽比伸缩,保持图像整幅,黑色填充目标区域边框。

PG_DEV_VIDEO_OUT_FILL_MODE_SRC_FIT_DST, // 不等长宽比伸缩,图像刚好填充目标区域。

} PG_DEV_VIDEO_OUT_FILL_MODE_E;

PG_DEV_VIDEO_OUT_ROTATE_E:视频输出图像旋转角度

typedef enum tagPG_DEV_VIDEO_OUT_ROTATE_E {

PG_DEV_VIDEO_OUT_ROTATE_0,

PG_DEV_VIDEO_OUT_ROTATE_90, // 顺时针旋转90度

PG_DEV_VIDEO_OUT_ROTATE_180, // 顺时针旋转180度

PG_DEV_VIDEO_OUT_ROTATE_270, // 顺时针旋转270度

} PG_DEV_VIDEO_OUT_ROTATE_E;

PG_DEV_VIDEO_OUT_PARAM_E:视频输出参数的条目

typedef enum tagPG_DEV_VIDEO_OUT_PARAM_E {

PG_DEV_VIDEO_OUT_PARAM_PIXEL_FORMAT, // 输出的视频像素数据的格式: I402或RGB24

PG_DEV_VIDEO_OUT_PARAM_FRAME_RATE, // 视频输出的帧率

PG_DEV_VIDEO_OUT_PARAM_BUTT

} PG_DEV_VIDEO_OUT_PARAM_E;

参数条目的说明:

PG_DEV_VIDEO_OUT_PARAM_PIXEL_FORMAT:输出的视频像素数据的格式: I402或RGB24

调用pgDevVideoOutGetParam()获取当前Peergine中间件输出的视频图像的像素数据的格式,有效值为’PG_DEV_VIDEO_OUT_FMT_RGB24’和’PG_DEV_VIDEO_OUT_FMT_I420’。

调用pgDevVideoOutSetParam()修改Peergine中间件输出视频图像的像素数据的格式,从uValue参数传入像素的格式类型,有效值为’PG_DEV_VIDEO_OUT_FMT_RGB24’和’PG_DEV_VIDEO_OUT_FMT_I420’。

PG_DEV_VIDEO_OUT_PARAM_FRAME_RATE:视频输出的帧率

调用pgDevVideoOutGetParam()获取视频流的帧率。

3)结构体:

PG_DEV_VIDEO_OUT_CALLBACK_S:视频输出回调接口结构

typedef struct tagPG_DEV_VIDEO_OUT_CALLBACK_S {

// 打开视频输出设备

int (*pfnVideoOutOpen)(unsigned int uDevNO);

// 关闭视频输出设备

void (*pfnVideoOutClose)(int iDevID);

// 播放显示视频帧图像

void (*pfnVideoOutImage)(int iDevID, const void* lpData,

unsigned int uDataSize, unsigned int uFormat, unsigned int uFlag,

int iPosX, int iPosY, unsigned int uWidth, unsigned int uHeight,

unsigned int uFillMode, unsigned int uRotate);

// 清除视频图像显示窗口

void (*pfnVideoOutClean)(int iDevID);

} PG_DEV_VIDEO_OUT_CALLBACK_S;

4)API函数:

pgDevVideoOutSetCallback:设置视频输出回调接口

/**

* 描述:设备回调接口

* 阻塞方式:非阻塞,立即返回。

* lpstCallback:[IN] 回调接口结构指针

*/

void pgDevVideoOutSetCallback(const PG_DEV_VIDEO_OUT_CALLBACK_S* lpstCallback)

pgDevVideoOutEventProc:视频输出事件处理

/**

* 描述:发送视频输出事件到 Peergine中间件中

* 阻塞方式:阻塞,视频输出事件缓冲到 Peergine中间件队列后返回

* iDevID: [IN] 设备ID。回调函数’pfnVideoOutOpen’的返回值

* uEvent: [IN] 视频帧的格式,见枚举 ‘PG_DEV_VIDEO_OUT_EVENT_E’

* lpParam: [IN] 事件的参数

*/

void pgDevVideoOutEventProc(int iDevID, unsigned int uEvent, const void* lpParam)

pgDevVideoOutSetPixFormat:设置视频输出的像素数据格式

/**

* 描述:设置视频输出的像素数据格式。

* 此函数必须在回调函数pfnVideoOutOpen()的函数体内调用。

* 阻塞方式:非阻塞,立即返回

* uDevNO: [IN] 视频输出设备的编号。也就是回调函数pfnVideoOutOpen()的uDevNO输入参数

* uFormat: [IN] 视频帧的格式。有效值为:

* ’PG_DEV_VIDEO_OUT_FMT_RGB24’或’PG_DEV_VIDEO_OUT_FMT_I420’。

* 返回值:0为失败,非0为成功。

*/

unsigned int pgDevVideoOutSetPixFormat(unsigned int uDevNO, unsigned int uFormat)

pgDevVideoOutSetParam:设置视频输出的参数

/**

* 描述:设置视频输出的参数。

* 此函数必须在回调函数pfnVideoOutOpen()的函数体内调用。

* 阻塞方式:非阻塞,立即返回

* uDevNO: [IN] 视频输出设备的编号。也就是回调函数pfnVideoOutOpen()的uDevNO输入参数

* uItem: [IN] 参数项条目。有效值参考枚举‘PG_DEV_VIDEO_OUT_PARAM_E’

* uValue: [IN] 参数项的值。有效值为参考枚举‘PG_DEV_VIDEO_OUT_PARAM_E’的参数说明

* 返回值:小于0为失败,等于0为成功。

*/

int pgDevVideoOutSetParam(unsigned int uDevNO, unsigned int uItem, unsigned int uValue)

pgDevVideoOutGetParam:获取视频输出的参数

/**

* 描述:获取视频输出的参数。

* 此函数必须在回调函数pfnVideoOutOpen()的函数体内调用。

* 阻塞方式:非阻塞,立即返回

* uDevNO: [IN] 视频输出设备的编号。也就是回调函数pfnVideoOutOpen()的uDevNO输入参数

* uItem: [IN] 参数项条目。有效值参考枚举‘PG_DEV_VIDEO_OUT_PARAM_E’

* 返回值:小于0为失败,大于等于0位获取到参数值。

*/

int pgDevVideoOutGetParam(unsigned int uDevNO, unsigned int uItem)

5)回调函数:

pfnVideoOutOpen:打开视频输出设备

/**

* 描述:打开视频输出设备。

* uDevNO: [IN] 视频输出设备的编号。

* 返回值:小于0失败,大于0返回设备ID。

*/

int (*pfnVideoOutOpen)(unsigned int uDevNO);

pfnVideoOutClose:关闭视频输出设备

/**

* 描述:关闭视频输出设备。

* iDevID:[IN] 视频输出设备的ID,也就是’pfnVideoOutOpen’回调函数的返回值。

*/

void (*pfnVideoOutClose)(int iDevID);

pfnVideoOutImage:播放显示视频帧图像

/**

* 描述:播放显示视频帧图像。

* iDevID: [IN] 视频输出设备的ID,也就是’pfnVideoOutOpen’回调函数的返回值。

* lpData: [IN] 视频数据指针。

* uDataSize: [IN] 视频数据长度。

* uFormat: [IN] 图像格式,参考枚举’PG_DEV_VIDEO_OUT_FMT_E’定义。

* uFlag: [IN] 标志位,参考枚举’PG_DEV_VIDEO_OUT_FLAG_E’定义。

* iPosX: [IN] 显示图像的左上角横坐标。

* iPosY: [IN] 显示图像的左上角纵坐标。

* uWidth: [IN] 图像宽度。

* uHeight: [IN] 图像高度。

* uFillMode: [IN] 图像的填充模式,参考枚举’PG_DEV_VIDEO_OUT_FILL_MODE_E’定义。

* uRotate: [IN] 图像的需要旋转的角度,参考枚举’PG_DEV_VIDEO_OUT_ROTATE_E’定义。

*/

void (*pfnVideoOutImage)(int iDevID, const void* lpData,

unsigned int uDataSize, unsigned int uFormat, unsigned int uFlag,

int iPosX, int iPosY, unsigned int uWidth, unsigned int uHeight,

unsigned int uFillMode, unsigned int uRotate);

pfnVideoOutClean:清除视频播放窗口

/**

* 描述:清除视频播放窗口。

* iDevID: [IN] 视频输出设备的ID,也就是’pfnVideoOutOpen’回调函数的返回值。

*/

void (*pfnVideoOutClean)(int iDevID);

4. 音频输入API接口(pgLibDevAudioIn.h)

1)说明

从Peergine中间件的1.42.0版本开始,增加了内置的音频输入数据转换的功能,应用程序可以在pfnAudioInOpen()回调函数里面,调用pgDevAudioInSetParam()函数设置输入的音频流数据的参数的值,就可以启用Peergine中间件内置的音频输入数据转换的功能。

2)常量:

PG_DEV_AUDIO_IN_FMT_E:音频输入格式

typedef enum tagPG_DEV_AUDIO_IN_FMT_E {

PG_DEV_AUDIO_IN_FMT_PCM16, // 音频编码格式为PCM16。

PG_DEV_AUDIO_IN_FMT_G711A, // 音频编码格式为G711A。

PG_DEV_AUDIO_IN_FMT_AAC, // 音频编码格式为AAC。

PG_DEV_AUDIO_IN_FMT_G711U, // 音频编码格式为G711U。

PG_DEV_AUDIO_IN_FMT_BUTT

} PG_DEV_AUDIO_IN_FMT_E;

PG_DEV_AUDIO_IN_PARAM_E:音频输入参数的条目

typedef enum tagPG_DEV_AUDIO_IN_PARAM_E {

PG_DEV_AUDIO_IN_PARAM_SAMPLE_RATE, // 输入的音频数据的帧率

PG_DEV_AUDIO_IN_PARAM_DEST_FORMAT, // 指定把输入的音频数据转换成的目标编码格式

PG_DEV_AUDIO_IN_PARAM_PACKET_SAMPLES, // 输入的音频数据的帧长度(采样点数)

PG_DEV_AUDIO_IN_PARAM_BUTT

} PG_DEV_AUDIO_IN_PARAM_E;

参数条目的说明:

PG_DEV_AUDIO_IN_PARAM_SAMPLE_RATE:输入的音频数据的帧率

调用pgDevAudioInSetParam()设置音频输入数据的采样率。从uValue传入采样率,有效值为8000、16000、32000、11025、22050、44100、48000,默认值为11025。

PG_DEV_AUDIO_IN_PARAM_DEST_FORMAT:指定把输入的音频数据转换成的目标编码格式

调用pgDevAudioInSetParam()设置音频输入数据的内置转换后的编码格式。从uValue传入编码格式,有效值为见枚举’PG_DEV_AUDIO_IN_FMT_E’的定义,默认值为’PG_DEV_AUDIO_IN_FMT_PCM16’。

PG_DEV_AUDIO_IN_PARAM_PACKET_SAMPLES:输入的音频数据的帧长度(采样点数)

调用pgDevAudioInSetParam()设置音频输入数据的每帧采样点个数。从uValue传入每帧的采样点个数,默认值为当前采样率下40毫秒的采样点个数。

3)结构体:

PG_DEV_AUDIO_IN_CALLBACK_S:音频输入回调接口结构

typedef struct tagPG_DEV_AUDIO_IN_CALLBACK_S {

// 打开音频采集设备,开始音频采集

int (*pfnAudioInOpen)(unsigned int uDevNO, unsigned int uSampleBits,

unsigned int uSampleRate, unsigned int uChannels, unsigned int uPackBytes);

// 停止音频采集,关闭音频采集设备

void (*pfnAudioInClose)(int iDevID);

} PG_DEV_AUDIO_IN_CALLBACK_S;

4)API函数:

pgDevAudioInSetCallback:设置音频输入回调接口

/**

* 描述:设备回调接口

* 阻塞方式:非阻塞,立即返回。

* lpstCallback:[IN] 回调接口结构指针

*/

void pgDevAudioInSetCallback(const PG_DEV_AUDIO_IN_CALLBACK_S* lpstCallback);

pgDevAudioInRecordProc把采集到的音频数据输入到中间件

/**

* 描述:把采集到的音频数据输入到中间件。

* 注意:输入的音频数据的采样率必须为11025,一次输入的音频数据长度必须为441个采样点。

* 如果采集到的音频数据的格式和帧长不符合以上2点,则需要使用“音频转换API接口”进行转换。

* 阻塞方式:阻塞,音频数据缓冲到 Peergine中间件队列后返回

* iDevID: [IN] 设备ID。回调函数’pfnAudioInOpen’的返回值。

* lpData: [IN] 音频数据的缓冲区指针。

* uDataSize: [IN] 音频数据的长度(字节),(注意:一次输入的音频数据长度必须为441个采样点)

* uFormat: [IN] 音频的格式,见枚举 ‘ PG_DEV_AUDIO_IN_FMT_E ‘

* uDelayMs: [IN] 音频从 采集、传输 到 播放 的延时,给0可以自动适配。给合适的值可以优化用户体验。

*/

void pgDevAudioInRecordProc(int iDevID, const void* lpData,

unsigned int uDataSize, unsigned int uFormat, unsigned int uDelayMs);

pgDevAudioInSetParam:设置音频输入的参数

/**

* 描述:设置音频输入的参数。

* 此函数必须在回调函数pfnAudioInOpen()的函数体内调用。

* 阻塞方式:非阻塞,立即返回

* uDevNO: [IN] 音频输入设备的编号。也就是回调函数pfnAudioInOpen()的uDevNO输入参数

* uItem: [IN] 参数项条目。有效值参考枚举‘PG_DEV_AUDIO_IN_PARAM_E’

* uValue: [IN] 参数项的值。有效值为参考枚举‘PG_DEV_AUDIO_IN_PARAM_E’的参数说明

* 返回值:小于0为失败,等于0为成功。

*/

int pgDevAudioInSetParam(unsigned int uDevNO, unsigned int uItem, unsigned int uValue)

pgDevAudioInGetParam:获取音频输入的参数

/**

* 描述:获取音频输入的参数。

* 此函数必须在回调函数pfnAudioInOpen()的函数体内调用。

* 阻塞方式:非阻塞,立即返回

* uDevNO: [IN] 音频输入设备的编号。也就是回调函数pfnAudioInOpen()的uDevNO输入参数

* uItem: [IN] 参数项条目。有效值参考枚举‘PG_DEV_AUDIO_IN_PARAM_E’

* 返回值:小于0为失败,大于等于0位获取到参数值。

*/

int pgDevAudioInGetParam(unsigned int uDevNO, unsigned int uItem)

5)回调函数:

pfnAudioInOpen:打开音频采集设备进行采集

/**

* 描述:打开音频采集设备进行采集。

* uDevNO: [IN] 音频采集的设备编号,当有多个音频采集设备时区分不同的设备。

* uSampleBits: [IN] 音频的采样位数,默认16bit。

* uSampleRate: [IN] 音频的采样率,默认11025。

* uChannels: [IN] 声道数,默认单声道。

* uPackBytes: [IN] 每个数据包的字节数(只支持441个采样点)。

* 返回值:小于0失败,大于0返回设备ID。

*/

int (*pfnAudioInOpen)(unsigned int uDevNO, unsigned int uSampleBits,

unsigned int uSampleRate, unsigned int uChannels, unsigned int uPackBytes);

pfnAudioInClose:关闭音频采集设备停止采集

/**

* 描述:关闭音频采集设备,停止采集。

* iDevID:[IN] 音频采集设备的ID,也就是’ pfnAudioInOpen’回调函数的返回值。

*/

void (*pfnAudioInClose)(int iDevID);

5. 音频输出API接口(pgLibDevAudioOut.h)

1)说明

从Peergine中间件的1.42.0版本开始,增加了内置的音频输出数据转换的功能,应用程序可以在pfnAudioOutOpen()回调函数里面,调用pgDevAudioOutSetParam()函数设置输出的音频流数据的参数的值,就可以启用Peergine中间件内置的音频输出数据转换的功能。

2)常量:

PG_DEV_AUDIO_OUT_FMT_E:音频输出格式

typedef enum tagPG_DEV_AUDIO_OUT_FMT_E {

PG_DEV_AUDIO_OUT_FMT_PCM16, // 输出音频的编码格式是PCM16。

PG_DEV_AUDIO_OUT_FMT_G711A, // 输出音频的编码格式是G711A。

PG_DEV_AUDIO_OUT_FMT_AAC, // 输出音频的编码格式是AAC。

PG_DEV_AUDIO_OUT_FMT_G711U, // 输出音频的编码格式是G711U。

PG_DEV_AUDIO_OUT_FMT_BUTT

} PG_DEV_AUDIO_OUT_FMT_E;

PG_DEV_AUDIO_OUT_PARAM_E:音频输出的参数条目

typedef enum tagPG_DEV_AUDIO_OUT_PARAM_E {

PG_DEV_AUDIO_OUT_PARAM_SAMPLE_RATE, // 输出的音频数据的采样率

PG_DEV_AUDIO_OUT_PARAM_DEST_FORMAT, // 输出的音频数据的编码格式

PG_DEV_AUDIO_OUT_PARAM_PACKET_SAMPLES, // 输出的音频数据的帧长度(采样点数)

PG_DEV_AUDIO_OUT_PARAM_PLAY_SLENT, // 是否在没有接收到网络的音频数据时输出静音数据

PG_DEV_AUDIO_OUT_PARAM_SYNC_INPUT, // 是否同步音频输出和音频输入(回音消除时需要)

PG_DEV_AUDIO_OUT_PARAM_BUTT

} PG_DEV_AUDIO_OUT_PARAM_E;

参数条目的说明:

PG_DEV_AUDIO_OUT_PARAM_SAMPLE_RATE:输出的音频数据的采样率

调用pgDevAudioOutSetParam()设置音频输出数据的采样率。从uValue传入采样率,有效值为8000、16000、32000、11025、22050、44100、48000,默认值为11025。

PG_DEV_AUDIO_OUT_PARAM_DEST_FORMAT:输出的音频数据的编码格式

调用pgDevAudioOutSetParam()设置音频输出数据的编码格式。从uValue传入编码格式,有效值为见枚举’PG_DEV_AUDIO_OUT_FMT_E’的定义,默认值为’PG_DEV_AUDIO_OUT_FMT_PCM16’。

PG_DEV_AUDIO_OUT_PARAM_PACKET_SAMPLES:输出的音频数据的帧长度(采样点数)

调用pgDevAudioOutSetParam()设置音频输出数据的每帧采样点个数。从uValue传入每帧的采样点个数,默认值为当前采样率下40毫秒的采样点个数。(注:建议从uValue传入的值,为当前采样率下40毫秒的采样点个数的整倍数)

PG_DEV_AUDIO_OUT_PARAM_PLAY_SLENT:是否在没有接收到网络的音频数据时输出静音数据

调用pgDevAudioOutSetParam()设置是否输出音频的静音数据。uValue的有效值:1为启用静音输出,0为禁止静音输出,默认值为0

PG_DEV_AUDIO_OUT_PARAM_SYNC_INPUT:是否同步音频输出和音频输入(回音消除时需要)

调用pgDevAudioOutSetParam()设置音频数据的输出是否与音频数据的输入进行同步。uValue的有效值:1为启用同步,0为禁止同步,默认值为1

3)结构体:

PG_DEV_AUDIO_OUT_CALLBACK_S:音频输出回调接口结构

typedef struct tagPG_DEV_AUDIO_OUT_CALLBACK_S {

// 打开音频播放设备

int (*pfnAudioOutOpen)(unsigned int uDevNO, unsigned int uSampleBits,

unsigned int uSampleRate, unsigned int uChannels, unsigned int uPackBytes);

// 关闭音频播放设备

void (*pfnAudioOutClose)(int iDevID);

// 播放音频数据

int (*pfnAudioOutPlay)(int iDevID, const void* lpData,

unsigned int uDataSize, unsigned int uFormat);

} PG_DEV_AUDIO_OUT_CALLBACK_S;

4)API函数:

pgDevAudioOutSetCallback:设置音频输出回调接口

/**

* 描述:设备回调接口。

* 阻塞方式:非阻塞,立即返回。

* lpstCallback: [IN] 回调接口结构指针。

*/

void pgDevAudioOutSetCallback (const PG_DEV_AUDIO_IN_CALLBACK_S* lpstCallback);

pgDevAudioOutPlayedProc:反馈实际已经播放的音频数据长度

/**

* 描述:反馈实际已经在声卡上播放的音频数据长度给中间件。

* 注:此函数在Peergine中间件1.42.0以上的版本中作废。

* 阻塞方式:阻塞,取出的音频数据播放完成返回。

* iDevID: [IN] 设备ID。回调函数’ pfnAudioOutOpen’的返回值。

* uPlayedSize: [IN] 已经在声卡上实际累计播放的音频数据长度(BYTE)。

* uDelayMs: [IN] 音频播放延时。给0可以自动适配,给合适的值(160ms左右)可以优化用户体验。

*/

void pgDevAudioOutPlayedProc(int iDevID, unsigned int uPlayedSize, unsigned int uDelayMs);

pgDevAudioOutPlaySilent:开启SDK输出静音数据的机制

/**

* 描述:开启SDK输出静音数据的机制。

* 阻塞方式:非阻塞,立即返回。

* uDevNO: [IN] 扬声器编号,与回调函数’pfnAudioOutOpen’的uDevNO参数相同。

* uEnable: [IN] 是否开启。1为开启,0关闭,默认为0。

* 返回值:0失败,非0成功

*/

unsigned int pgDevAudioOutPlaySilent(unsigned int uDevNO, unsigned int uEnable);

pgDevAudioOutSetParam:设置音频输出的参数

/**

* 描述:设置音频输出的参数。

* 此函数必须在回调函数pfnAudioOutOpen()的函数体内调用。

* 阻塞方式:非阻塞,立即返回

* uDevNO: [IN] 音频输出设备的编号。也就是回调函数pfnAudioOutOpen()的uDevNO输入参数

* uItem: [IN] 参数项条目。有效值参考枚举‘PG_DEV_AUDIO_OUT_PARAM_E’

* uValue: [IN] 参数项的值。有效值为参考枚举‘PG_DEV_AUDIO_OUT_PARAM_E’的参数说明

* 返回值:小于0为失败,等于0为成功。

*/

int pgDevAudioOutSetParam(unsigned int uDevNO, unsigned int uItem, unsigned int uValue)

pgDevAudioOutGetParam:获取音频输出的参数

/**

* 描述:获取音频输出的参数。

* 此函数必须在回调函数pfnAudioOutOpen()的函数体内调用。

* 阻塞方式:非阻塞,立即返回

* uDevNO: [IN] 音频输出设备的编号。也就是回调函数pfnAudioOutOpen()的uDevNO输入参数

* uItem: [IN] 参数项条目。有效值参考枚举‘PG_DEV_AUDIO_OUT_PARAM_E’

* 返回值:小于0为失败,大于等于0位获取到参数值。

*/

int pgDevAudioOutGetParam(unsigned int uDevNO, unsigned int uItem)

5)回调函数:

pfnAudioOutOpen:打开音频播放设备

/**

* 描述:打开音频播放设备。

* uDevNO: [IN] 音频播放的设备编号,当有多个音频播放设备时区分不同的设备。

* uSampleBits: [IN] 音频的采样位数,默认16bit。

* uSampleRate: [IN] 音频的采样率,默认11025。

* uChannels: [IN] 声道数,默认单声道。

* uPackBytes: [IN] 每个数据包的字节数(只支持441个采样点)。

* 返回值:小于0失败,大于0返回设备ID。

*/

int (*pfnAudioOutOpen)(unsigned int uDevNO, unsigned int uSampleBits,

unsigned int uSampleRate, unsigned int uChannels, unsigned int uPackBytes);

pfnAudioOutClose:关闭音频播放设备

/**

* 描述:关闭音频播放设备。

* iDevID: [IN] 音频播放设备的ID,也就是’ pfnAudioOutOpen’回调函数的返回值。

*/

void (*pfnAudioOutClose)(int iDevID);

pfnAudioOutPlay:播放音频数据

/**

* 描述:播放音频数据。

* 注意:输出的音频数据的采样率为11025,音频数据长度为441个采样点。

* 如果播放接口的音频数据的格式和帧长不符合以上2点,则需要使用“音频转换API接口”进行转换。

* iDevID: [IN] 音频播放设备的ID,也就是’ pfnAudioOutOpen’回调函数的返回值。

* lpData: [IN]要播放的音频数据。

* uDataSize: [IN]要播放的音频数据长度(字节数),(只支持441个采样点)。

* uFormat: [IN] 音频的格式, 详情请看枚举 ‘PG_DEV_AUDIO_OUT_FMT_E’.

*/

int (*pfnAudioOutPlay)(int iDevID, const void* lpData,

unsigned int uDataSize, unsigned int uFormat);

6. 音频转换API接口(pgLibDevAudioConvert.h)

1)说明:

在Peergine系统以及由Peergine经过裁剪和封装衍生出来的系列SDK中,音频通话的数据都是以统一的采样率和帧长度进行通信传输的。Peergine使用的统一音频采样率为11025,音频的帧长度为441个采样点。但是,当Peergine和SDK应用在各种设备上时,有些设备上的音频采集和播放就不一定支持11025的采样率和441个采样点的帧长度。所以, Peergine和SDK提供了一套音频转换的API来进行音频采样率、帧长度,以及格式的转换。以便在Peergine和SDK与设备之间进行音频采集和播放对接时,有更强的适应性。

音频转换以“转换队列”的方式实现,使用步骤为:

(1)创建转换队列(传入转换参数)

(2)把待转换的音频数据压入队列(每次压入一帧数据)

(3)从队列弹出转换后的音频数据(每次弹出一帧数据)

(4)重复(2)和(3)步,直到完成所有数据转换

(5)销毁转换队列

以下“API函数”章节详细叙述的音频转换API的说明。

从Peergine中间件1.42.0版本开始,增加支持内置的音频输入输出转换功能,开发者只需要调用pgDevAudioInSetParam()或pgDevAudioOutSetParam()设置音频数据的转换参数,就可以完成转换操作。详情请参考音频输入接口和音频输出接口章节。

2)常量:

PG_DEV_AUDIO_CVT_FMT_E:音频转换格式

/**

* 音频转换的格式枚举

*/

typedef enum tagPG_DEV_AUDIO_CVT_FMT_E {

PG_DEV_AUDIO_CVT_FMT_PCM16 = 0, // PCM16格式

PG_DEV_AUDIO_CVT_FMT_G711A = 1, // G711A(PCMA) 格式

PG_DEV_AUDIO_CVT_FMT_G711U = 2, // G711U(PCMU) 格式

PG_DEV_AUDIO_CVT_FMT_AAC = 3, // AAC 格式(只有包含软件AAC编码的SDK中支持)

} PG_DEV_AUDIO_CVT_FMT_E;

3)API函数:

pgDevAudioConvertAlloc:创建转换队列

/**

* 描述:创建转换队列

* 参数:

* uDirect: [in] 转换方向:0为录音转换(设备到SDK),1为放音转换(SDK到设备)

* uDstFormat: [in] 转换后的音频数据格式,见枚举‘PG_DEV_AUDIO_CVT_FMT_E’

* uDevSampleRate: [in] 设备端音频数据的采样率。

* 有效值:8000, 16000, 32000, 11025, 22050, 44100, 48000

* uDevSampleSize: [in] 设备端每帧音频数据的采样点数。

* 返回值:

* 小于0: 失败, 大于0: 转换队列的ID

*/

int pgDevAudioConvertAlloc(unsigned int uDirect, unsigned int uDstFormat,

unsigned int uDevSampleRate, unsigned int uDevSampleSize);

pgDevAudioConvertFree:销毁转换队列

/**

* 描述:销毁转换队列

* 参数:

* iCvtID: [in] 转换队列的ID(pgDevAudioConvertAlloc()函数的返回值)

* 返回值:

* 无

*/

void pgDevAudioConvertFree(int iCvtID);

pgDevAudioConvertPush:把待转换的音频数据压入到队列中

/**

* 描述:把待转换的音频数据压入到队列中

* 参数:

* iCvtID: [in] 转换队列的ID(pgDevAudioConvertAlloc()函数的返回值)

* uSrcFormat: [in] 转换前的音频数据格式,见枚举‘PG_DEV_AUDIO_CVT_FMT_E’

* lpSrcData: [in] 转换前的数据缓冲区地址

* uSrcDataSize: [in] 转换前的数据长度

* 返回值:

* 小于0: 失败, 大于等于0: 已经压入到队列的数据长度(通常等于uSrcDataSize)

*/

int pgDevAudioConvertPush(int iCvtID, unsigned int uSrcFormat,

const void* lpSrcData, unsigned int uSrcDataSize);

pgDevAudioConvertPop:把转换后的数据从队列弹出(只弹出数据缓冲区的地址,已经作废)

/**

* 描述:把转换后的数据从队列弹出(只输出数据缓冲区的地址,已经作废)

* 此函数作废,请使用pgDevAudioConvertPopS()替代。

* 参数:

* iCvtID: [in] 转换队列的ID(pgDevAudioConvertAlloc()函数的返回值)

* ppDstData: [out] 转换后的音频数据缓冲区地址的指针(注意:pgDevAudioConvertFree()后不能再引用)

* lpuDstDataSize: [in] 转换后的数据长度

* 返回值:

* 小于0: 失败,等于0: 队列中没有转换后的数据,大于0:转换后的数据长度

*/

int pgDevAudioConvertPop(int iCvtID, void **ppDstData, unsigned int* lpuDstDataSize);

pgDevAudioConvertPopS:把转换后的数据从队列弹出(把数据从队列复制出来)

/**

* 描述:把转换后的数据从队列弹出(把数据从队列复制出来)

* 参数:

* iCvtID: [in] 转换队列的ID(pgDevAudioConvertAlloc()函数的返回值)

* lpDstData: [out] 接收转换后的音频数据缓冲区地址

* uDstDataSize: [in] 接收转换后的音频数据缓冲区的长度

* 返回值:

* 小于0: 失败,等于0: 队列中没有转换后的数据,大于0:转换后的数据长度

*/

int pgDevAudioConvertPopS(int iCvtID, void *lpDstData, unsigned int uDstDataSize);

7. 代码样例:

1)视频输入对接样例伪码:

// 假设这是视频采集处理回调函数,得到视频帧数据。

static int s_iVideoInDevID = -1;

void OnPreviewFrame(void *lpFrmData, unsigned int uFrmSize)

{

// 调用硬件编码器,把视频帧压缩成H.264格式。

// H264 Codec . . .

void* pCmpData = 压缩后的数据指针;

unsigned int uCmpSize = 压缩后的数据长度;

unsigned int uFlag = 0;

if (是关键帧) {

uFlag |= PG_DEV_VIDEO_IN_FLAG_KEY_FRAME;

}

// 把视频帧数据输入到Peergine中间件.

pgDevVideoInCaptureProc(s_iVideoInDevID, pCmpData, uCmpSize, PG_DEV_VIDEO_IN_FMT_H264, uFlag);

}

// 实现视频采集回调接口。

static int VideoInOpen(unsigned int uDevNO, unsigned int uPixBytes,

unsigned int uWidth, unsigned int uHeight, unsigned int uBitRate,

unsigned int uFrmRate, unsigned int uKeyFrmRate)

{

// 打开视频设备,进行视频采集。

// . . .

s_iVideoInDevID = (uDevNO + 1);

return s_iVideoInDevID; // 返回采集设备的ID

}

static void VideoInClose(int iDevID)

{

// 关闭视频采集设备,停止采集。

// . . .

s_iVideoInDevID = -1;

}

static void VideoInCtrl(int iDevID, unsigned int uCtrl, unsigned int uParam)

{

// 控制视频采集。

if (uCtrl == PG_DEV_VIDEO_IN_CTRL_PULL_KEY_FRAME) {

// 强制编码器立即产生一个关键帧.

// …

}

}

// 视频输入回调函数指针结构

static PG_DEV_VIDEO_IN_CALLBACK_S s_stCallback_VideoIn = {

VideoInOpen,

VideoInClose,

VideoInCtrl

};

//注册回调结构体

int main()

{

//注册视频输入的回调函数

pgDevVideoInSetCallback(&s_stCallback_VideoIn);

// . . .

}

2)视频输出对接样例伪码:

// 打开视频输出

static int VideoOutOpen(unsigned int uDevNO)

{

// 创建显示视频图像的view或window

// …

return (uDevNO + 1);

}

// 关闭视频输出

static void VideoOutClose(int iDevID)

{

// 销毁显示视频图像的view或window

// …

}

// 输出每帧视频图像数据

static void VideoOutImage(int iDevID, const void* lpData, unsigned int uDataSize,

unsigned int uFormat, unsigned int uFlag, int iPosX, int iPosY, unsigned int uWidth,

unsigned int uHeight, unsigned int uFillMode, unsigned int uRotate)

{

// 对视频帧数据进行解码,并在View或Window里显示图像

// …

}

// 清除视频输出图像

static void VideoOutClean(int iDevID)

{

// 清除view或window中的图像

// …

}

// 视频输出回调函数指针结构

static PG_DEV_VIDEO_OUT_CALLBACK_S s_stCallback_VideoOut = {

VideoOutOpen,

VideoOutClose,

VideoOutImage,

VideoOutClean

};

//注册回调结构体

int main()

{

//注册视频输出的回调函数

pgDevVideoOutSetCallback(&s_stCallback_VideoOut);

// . . .

}

3)音频输入对接样例伪码:

//以下是音频输入扩展接口使用的示例伪代码

// 假设这是音频采集处理回调函数,得到音频数据。

static int s_iAudioInDevID = -1;

void OnAudioRecord(void* lpData, unsigned int uDataSize)

{

// 其他音频数据处理。

// 例如:压缩编码……

// 将音频数据输入到Peergine中间件.

pgDevAudioInRecordProc(s_iAudioInDevID, lpData, uDataSize, PG_DEV_AUDIO_IN_FMT_PCM16, 0);

}

// 打开音频采集设备进行采集

static int AudioInOpen(unsigned int uDevNO, unsigned int uSampleBits,

unsigned int uSampleRate, unsigned int uChannels, unsigned int uPackBytes)

{

// 打开音频采集设备,开始采集音频。

// ……

s_iAudioInDevID = (uDevNO + 1);

return s_iAudioInDevID; // 返回采集设备的ID

}

//停止音频采集处理回调线程,释放设备ID

static void AudioInClose(int iDevID)

{

// 关闭音频采集设备,停止音频采集

s_iAudioInDevID = -1;

}

// 音频输入回调函数指针结构

static PG_DEV_AUDIO_IN_CALLBACK_S s_stACallback_AudioIn = {

AudioInOpen,

AudioInClose

};

//注册回调结构体

int main()

{

//注册音频输入的回调函数

pgDevAudioInSetCallback(&s_stCallback_AudioIn);

// . . .

}

4)音频输出对接样例伪码:

//以下是音频输出扩展接口使用的示例伪代码

//假设这是音频播放进度通知函数。

// 注:在Peergine中间件1.42.0以后的版本,不需要调用此通知播放进度的函数。

static int s_iAudioOutDevID = -1;

static unsigned int s_uPlayedSize = 0;

void OnAudioPlayedProc(void* lpData,unsigned int uDataSize)

{

// 已经播放的数据长度累计。

s_uPlayedSize += uDataSize;

// 调用pgDevAudioOutPlayedProc通知中间件已经播放的数据长度

pgDevAudioOutPlayedProc(s_iAudioOutDevID, s_uPlayedSize, 0);

}

//启动一个从中间件获取音频数据的线程

static int AudioOutOpen(unsigned int uDevNO, unsigned int uSampleBits,

unsigned int uSampleRate, unsigned int uChannels, unsigned int uPackBytes)

{

// 打开音频播放设备

// ……

// 统计数据清零

s_uPlayedSize = 0;

s_iAudioOutDevID = (uDevNO + 1);

Return s_iAudioOutDevID;//播放设备ID

}

static void AudioOutClose(int iDevID)

{

// 关闭音频播放设备

s_iAudioOutDevID = -1;

}

//音频播放函数

int AudioOutPlay(int iDevID, const void* lpData,

unsigned int uDataSize, unsigned int uFormat)

{

//调用播放设备播放音频数据

// ……

return uDataSize;

}

// 音频输出回调函数指针结构

static PG_DEV_AUDIO_OUT_CALLBACK_S s_stACallback_AudioOut = {

AudioOutOpen,

AudioOutClose,

AudioOutPlay

};

//注册回调结构体

int main()

{

//注册音频输出的回调函数

pgDevAudioOutSetCallback(&s_stACallback_AudioOut);

// . . .

}

5)音频录音转换样例伪码:

// 假设设备端录音的格式是PCM16,采样率是8000,帧长是320个采样点。伪码如下:

static int s_iCvtIDIn = -1;

static int s_iDevID_AudioIn = -1;

static int AudioInOpen(unsigned int uDevNO, unsigned int uSampleBits,

unsigned int uSampleRate, unsigned int uChannels, unsigned int uPackBytes)

{

// 创建录音转换队列

s_iCvtIDIn = pgDevAudioConvertAlloc(0, PG_DEV_AUDIO_CVT_FMT_PCM16, 8000, 320);

s_iDevID_AudioIn = 1234;

return s_iDevID_AudioIn;

}

static void AudioInClose(int iDevID)

{

// 销毁转换队列

pgDevAudioConvertFree(s_iCvtIDIn);

s_iDevID_AudioIn = -1;

}

// 假设这是设备上音频采集数据输入函数

static void OnAudioInDataCallback(void *lpData, unsigned int uDataSize)

{

// 把采集到的音频帧数据压入到队列。

if (pgDevAudioConvertPush(s_iCvtIDIn, PG_DEV_AUDIO_CVT_FMT_PCM16, lpData, uDataSize) <= 0) {

return;

}

// 有可能转换前的音频帧的采样点数是转换后的音频帧的几倍,所以要循环弹出多次。

while (1) {

//从队列弹出转换后的音频帧数据。

unsigned char ucDataPop[2048];

int iPopSize = pgDevAudioConvertPopS(s_iCvtIDIn, ucDataPop, sizeof(ucDataPop));

if (iPopSize <= 0) {

break;

}

// 把转换后的音频帧输入给Peergine SDK

pgDevAudioInRecordProc(s_iDevID_AudioIn, ucDataPop,

iPopSize, PG_DEV_AUDIO_IN_FMT_PCM16, 0);

}

}

6)音频放音转换样例伪码:

// 假设设备端放音的格式是PCM16,采样率是16000,帧长是640个采样点。伪码如下:

static int s_iCvtIDOut = -1;

static int s_iDevID_AudioOut = -1;

static int AudioOutOpen(unsigned int uDevNO, unsigned int uSampleBits,

unsigned int uSampleRate, unsigned int uChannels, unsigned int uPackBytes)

{

// 创建放音转换队列

s_iCvtIDOut = pgDevAudioConvertAlloc(1, PG_DEV_AUDIO_CVT_FMT_PCM16, 16000, 640);

s_iDevID_AudioOut = 1234;

return s_iDevID_AudioOut;

}

static void AudioOutClose(int iDevID)

{

// 销毁转换队列

pgDevAudioConvertFree(s_iCvtIDOut);

s_iDevID_AudioOut = -1;

}

static int AudioOutPlay(int iDevID, const void* lpData, unsigned int uDataSize, unsigned int uFormat)

{

// 把播放的音频数据压入队列

int iRet = pgDevAudioConvertPush(s_iCvtIDOut, uFormat, lpData, uDataSize);

if (iRet <= 0) {

return -1;

}

// 有可能转换前的音频帧的采样点数是转换后的音频帧的几倍,所以要循环弹出多次。

while (1) {

// 从队列弹出转换后的数据。

unsigned char ucDataPop[2048];

int iPopSize = pgDevAudioConvertPopS(s_iCvtIDOut, ucDataPop, sizeof(ucDataPop));

if (iPopSize <= 0) {

break;

}

// 把转换后的音频帧数据在设备放音接口上播放。

dev_audio_play(ucDataPop, iPopSize);

}

return uDataSize;

}

8. Android的JNI接口类定义

1)视频输入接口(com.peergine.plugin.android.pgDevVideoIn)

package com.peergine.plugin.android;

public class pgDevVideoIn

{

// Video capture format enum.

public static final int PG_DEV_VIDEO_IN_FMT_RGB24 = 0;

public static final int PG_DEV_VIDEO_IN_FMT_YUV422SP = 1;

public static final int PG_DEV_VIDEO_IN_FMT_YUV420SP = 2;

public static final int PG_DEV_VIDEO_IN_FMT_YUYV = 3;

public static final int PG_DEV_VIDEO_IN_FMT_YV12 = 4;

public static final int PG_DEV_VIDEO_IN_FMT_MJPEG = 5;

public static final int PG_DEV_VIDEO_IN_FMT_VP8 = 6;

public static final int PG_DEV_VIDEO_IN_FMT_H264 = 7;

public static final int PG_DEV_VIDEO_IN_FMT_H265 = 8;

public static final int PG_DEV_VIDEO_IN_FMT_NV21 = 9;

public static final int PG_DEV_VIDEO_IN_FMT_I420 = 10;

// Video input flag

public static final int PG_DEV_VIDEO_IN_FLAG_KEY_FRAME = 0x0001;

// Video capture control command.

public static final int PG_DEV_VIDEO_IN_CTRL_PULL_KEY_FRAME = 0;

// Video capture parameter item.

public static final int PG_DEV_VIDEO_IN_PARAM_NO = 0; // Camera NO.

public static final int PG_DEV_VIDEO_IN_PARAM_FACING = 1; // Camera facing (0: back, 1: front)

public static final int PG_DEV_VIDEO_IN_PARAM_ROTATE = 2; // Camera capture rotate degrees

// (0, 90, 180, 270)

public static final int PG_DEV_VIDEO_IN_PARAM_IMG_ROTATE = 3; // Camera image data store rotate

// degrees (0, 90, 180, 270)

public static final int PG_DEV_VIDEO_IN_PARAM_ASSEM_FRAME = 4; // Enable to assem the h.264/h.265

// frames (0: disable, 1: enable)

// Callback interface.

public interface OnCallback {

///

// Return value:

// >= 0: the video capture device id.

// < 0: failed.

int Open(int iDevNO, int iPixBytes, int iWidth,

int iHeight, int iBitRate, int iFrmRate, int iKeyFrmRate);

void Close(int iDevID);

///

// Control the video input.

// iCtrl: [in] See the enum ‘PG_DEV_VIDEO_IN_CTRL_E’

// iParam: [in] Reserved.

void Ctrl(int iDevID, int iCtrl, int iParam);

}

///

// Set api callback functions

public native static void SetCallback(OnCallback callback);

///

// Device write the video capture data to peergine.

// iDevID: [in] Device id return by ‘pfnVideoInOpen’.

// byData: [in] Video frame data.

// iFormat: [in] Video frame format, see the enum ‘PG_DEV_VIDEO_IN_FMT_E’.

// iFlag: [in] Flag. see the enum ‘PG_DEV_VIDEO_IN_FLAG_E’.

public native static void CaptureProc(int iDevID, byte[] byData, int iFormat, int iFlag);

///

// Device write the video capture data to peergine.

// iDevID: [in] Device id return by ‘pfnVideoInOpen’.

// byData: [in] Video frame data.

// iOffset: [in] The offset of video frame data in ‘byData’ (byte).

// iDataSize: [in] Video frame data size(byte).

// iFormat: [in] Video frame format, see the enum ‘PG_DEV_VIDEO_IN_FMT_E’.

// iFlag: [in] Flag. see the enum ‘PG_DEV_VIDEO_IN_FLAG_E’.

public native static void CaptureProcExt(int iDevID, byte[] byData,

int iOffset, int iDataSize, int iFormat, int iFlag);

///

// Set the parameters’ value relate to ‘iDevNO’

// Note: This function can only call to in callback ‘pfnVideoInOpen’

// iDevNO: [in] The ‘iDevNO’ agument of ‘pfnVideoInOpen’.

// iItem: [in] The parameter item, see the enum ‘PG_DEV_VIDEO_IN_PARAM_E’.

// iValue: [in] The value of parameter. ‘iValue’ must >= 0

// return: <0: failed, >=0: success.

public native static int SetParam(int iDevNO, int iItem, int iValue);

///

// Get the parameters’ value relate to ‘iDevNO’

// Note: This function can only call to in callback ‘pfnVideoInOpen’

// iDevNO: [in] The ‘iDevNO’ agument of ‘pfnVideoInOpen’.

// iItem: [in] The item id of parameter, see the enum ‘PG_DEV_VIDEO_IN_PARAM_E’.

// return: <0: failed, >=0: The value of parameter.

public native static int GetParam(int iDevNO, int iItem);

}

2)视频输出接口(com.peergine.plugin.android.pgDevVideoOut)

package com.peergine.plugin.android;

public class pgDevVideoOut

{

///

// Video output format enum.

public static final int PG_DEV_VIDEO_OUT_FMT_RGB24 = 0;

public static final int PG_DEV_VIDEO_OUT_FMT_MJPEG = 1;

public static final int PG_DEV_VIDEO_OUT_FMT_VP8 = 2;

public static final int PG_DEV_VIDEO_OUT_FMT_H264 = 3;

public static final int PG_DEV_VIDEO_OUT_FMT_H265 = 4;

public static final int PG_DEV_VIDEO_OUT_FMT_I420 = 5;

///

// Video output flag

public static final int PG_DEV_VIDEO_OUT_FLAG_KEY_FRAME = 0x0001;

///

// Video output event.

public static final int PG_DEV_VIDEO_OUT_EVENT_PAINT = 0;

///

// Video fill mode

public static final int PG_DEV_VIDEO_OUT_FILL_MODE_DST_IN_SRC = 0;

public static final int PG_DEV_VIDEO_OUT_FILL_MODE_SRC_IN_DST = 1;

public static final int PG_DEV_VIDEO_OUT_FILL_MODE_SRC_FIT_DST = 2;

///

// Video rotate.

public static final int PG_DEV_VIDEO_OUT_ROTATE_0 = 0;

public static final int PG_DEV_VIDEO_OUT_ROTATE_90 = 1;

public static final int PG_DEV_VIDEO_OUT_ROTATE_180 = 2;

public static final int PG_DEV_VIDEO_OUT_ROTATE_270 = 3;

///

// Video output parameter item.

public static final int PG_DEV_VIDEO_OUT_PARAM_PIXEL_FORMAT = 0; // Value is ‘PG_DEV_VIDEO_OUT_FMT_RGB24’

// or ‘PG_DEV_VIDEO_OUT_FMT_I420’

public static final int PG_DEV_VIDEO_OUT_PARAM_FRAME_RATE = 1; // Get the frame rate of output video stream.

///

// Callback interface.

public interface OnCallback {

int Open(int iDevNO);

void Close(int iDevID);

void Image(int iDevID, byte[] byData, int iFormat, int iFlag,

int iPosX, int iPosY, int iWidth, int iHeight, int iFillMode, int iRotate);

void Clean(int iDevID);

}

///

// Set callback api functions

public native static void SetCallback(OnCallback callback);

///

// Process the video output event.

// iDevID: the return value of ‘OnCallback.Open()’

// iEvent: enum of ‘PG_DEV_VIDEO_OUT_EVENT_E’

public native static void EventProc(int iDevID, int iEvent, int iParam);

///

// Set output pixel format of ‘OnCallback.Image()’.

// iDevNO: the ‘iDevNO’ parameter of ‘OnCallback.Open()’

// iFormat: ‘PG_DEV_VIDEO_OUT_FMT_RGB24’ or ‘PG_DEV_VIDEO_OUT_FMT_I420′

public native static int SetPixFormat(int iDevNO, int iFormat);

///

// Set the parameters’ value relate to ‘iDevNO’

// Note: This function can only call to in callback ‘OnCallback.Open()’

// iDevNO: [in] The ‘iDevNO’ agument of ‘OnCallback.Open()’.

// iItem: [in] The parameter item, see the enum ‘PG_DEV_VIDEO_OUT_PARAM_E’.

// iValue: [in] The value of parameter.

// return: <0: failed, >=0: success.

public native static int SetParam(int iDevNO, int iItem, int iValue);

///

// Get the parameters’ value relate to ‘iDevNO’

// Note: This function can only call to in callback ‘pfnVideoOutOpen’

// iDevNO: [in] The ‘iDevNO’ agument of ‘OnCallback.Open()’.

// iItem: [in] The item id of parameter, see the enum ‘PG_DEV_VIDEO_OUT_PARAM_E’.

// return: <0: failed, >=0: The value of parameter.

public native static int GetParam(int iDevNO, int iItem);

}

3)音频输入接口(com.peergine.plugin.android.pgDevAudioIn)

package com.peergine.plugin.android;

public class pgDevAudioIn

{

///

// Audio capture format enum.

public static final int PG_DEV_AUDIO_IN_FMT_PCM16 = 0;

public static final int PG_DEV_AUDIO_IN_FMT_G711A = 1;

public static final int PG_DEV_AUDIO_IN_FMT_AAC = 2;

public static final int PG_DEV_AUDIO_IN_FMT_G711U = 3;

///

// Audio input parameter item.

public static final int PG_DEV_AUDIO_IN_PARAM_SAMPLE_RATE = 0;

public static final int PG_DEV_AUDIO_IN_PARAM_DEST_FORMAT = 1;

public static final int PG_DEV_AUDIO_IN_PARAM_PACKET_SAMPLES = 2;

///

// Callback interface.

public interface OnCallback {

int Open(int iDevNO, int iSampleBits, int iSampleRate, int iChannels, int iPackBytes);

void Close(int iDevID);

}

public native static void SetCallback(OnCallback callback);

///

// Device write the audio record data to peergine.

// iDevID: [in] The return value of ‘OnCallback.Open()’

// byData: [in] The byte array of content the audio data.

// iFormat: [in] Audio format, see the enum ‘PG_DEV_AUDIO_IN_FMT_E’.

// iDelayMs: [in] Recored audio delay(ms)

public native static void RecordProc(int iDevID, byte[] byData, int iFormat, int iDelayMs);

///

// Device write the audio record data to peergine.

// iDevID: [in] The return value of ‘OnCallback.Open()’

// byData: [in] The byte array of content the audio data.

// iOffset: [in] Offset of data in the byte array.

// iDataSize: [in] Size of data in the byte array.

// iFormat: [in] Audio format, see the enum ‘PG_DEV_AUDIO_IN_FMT_E’.

// iDelayMs: [in] Recored audio delay(ms)

public native static void RecordProcEx(int iDevID, byte[] byData,

int iOffset, int iDataSize, int iFormat, int iDelayMs);

///

// Set the parameters’ value relate to ‘iDevNO’

// Note: This function can only call to in callback ‘OnCallback.Open()’

// iDevNO: [in] The ‘iDevNO’ agument of ‘OnCallback.Open()’.

// iItem: [in] The parameter item, see the enum ‘PG_DEV_AUDIO_IN_PARAM_E’.

// iValue: [in] The value of parameter.

// return: <0: failed, >=0: success.

public native static int SetParam(int iDevNO, int iItem, int iValue);

///

// Get the parameters’ value relate to ‘iDevNO’

// Note: This function can only call to in callback ‘OnCallback.Open()’

// iDevNO: [in] The ‘iDevNO’ agument of ‘OnCallback.Open()’.

// iItem: [in] The item id of parameter, see the enum ‘PG_DEV_AUDIO_IN_PARAM_E’.

// return: <0: failed, >=0: The value of parameter.

public native static int GetParam(int iDevNO, int iItem);

}

4)音频输出接口(com.peergine.plugin.android.pgDevAudioOut)

package com.peergine.plugin.android;

public class pgDevAudioOut

{

///

// Audio output format enum.

public static final int PG_DEV_AUDIO_OUT_FMT_PCM16 = 0;

public static final int PG_DEV_AUDIO_OUT_FMT_G711A = 1;

public static final int PG_DEV_AUDIO_OUT_FMT_AAC = 2;

public static final int PG_DEV_AUDIO_OUT_FMT_G711U = 3;

///

// Audio output parameter item.

public static final int PG_DEV_AUDIO_OUT_PARAM_SAMPLE_RATE = 0;

public static final int PG_DEV_AUDIO_OUT_PARAM_DEST_FORMAT = 1;

public static final int PG_DEV_AUDIO_OUT_PARAM_PACKET_SAMPLES = 2;

public static final int PG_DEV_AUDIO_OUT_PARAM_PLAY_SLENT = 3;

public static final int PG_DEV_AUDIO_OUT_PARAM_SYNC_INPUT = 4;

///

// Callback interface.

public interface OnCallback {

int Open(int iDevNO, int iSampleBits, int iSampleRate, int iChannels, int iPackBytes);

void Close(int iDevID);

int Play(int iDevID, byte[] byData, int iFormat);

}

public native static void SetCallback(OnCallback callback);

public native static void PlayedProc(int iDevID, int iPlayedSize, int iDelayMs);

// Enable to play the silent data.

// iDevNO: [in] The speaker NO to enable

// iEnable: [in] Enable play silent. 1: enable, 0: disable.

// return: 1: success, 0: failed.

public native static int PlaySilent(int iDevNO, int iEnable);

///

// Set the parameters’ value relate to ‘iDevNO’

// Note: This function can only call to in callback ‘OnCallback.Open()’

// iDevNO: [in] The ‘iDevNO’ agument of ‘OnCallback.Open()’.

// iItem: [in] The parameter item, see the enum ‘PG_DEV_AUDIO_OUT_PARAM_E’.

// iValue: [in] The value of parameter.

// return: <0: failed, >=0: success.

public native static int SetParam(int iDevNO, int iItem, int iValue);

///

// Get the parameters’ value relate to ‘iDevNO’

// Note: This function can only call to in callback ‘OnCallback.Open()’

// iDevNO: [in] The ‘iDevNO’ agument of ‘OnCallback.Open()’.

// iItem: [in] The item id of parameter, see the enum ‘PG_DEV_AUDIO_OUT_PARAM_E’.

// return: <0: failed, >=0: The value of parameter.

public native static int GetParam(int iDevNO, int iItem);

}

5)音频转换接口(com.peergine.plugin.android.pgDevAudioConvert)

package com.peergine.plugin.android;

public class pgDevAudioConvert

{

///

// Audio capture format enum.

public static final int PG_DEV_AUDIO_CVT_FMT_PCM16 = 0;

public static final int PG_DEV_AUDIO_CVT_FMT_G711A = 1;

public static final int PG_DEV_AUDIO_CVT_FMT_G711U = 2;

public static final int PG_DEV_AUDIO_CVT_FMT_AAC = 3;

///

// Alloc a audio convert queue.

// iDirect: [in] 0: input, 1: output.

// iDstFormat: [in] The destinstion format.

// iDevSampleRate: [in] The device side sample rate.

// iDevSampleSize: [in] The device side sample number of one packet.

// Return value:

// <0: failed, >0: return the file descriptor id.

public native static int Alloc(int iDirect,

int iDstFormat, int iDevSampleRate, int iDevSampleSize);

///

// Free a audio convert queue.

// iCvtID: [in] The convert file descriptor id.

public native static void Free(int iCvtID);

///

// Push data into the audio convert queue.

// iCvtID: [in] The convert file descriptor id.

// iSrcFormat: [in] The source format.

// lpSrcData: [in] The source data buffer

// iSrcOffset: [in] The source data offset.

// iSrcDataSize: [in] The source data size.

// Return value:

// <0: failed, >=0: size of data in buffer.

public native static int Push(int iCvtID,

int iSrcFormat, byte[] bySrcData, int iSrcOffset, int iSrcDataSize);

///

// Pop data out from the audio convert queue.

// (It is safe, it copy the data out from queue to a buffer.)

// iCvtID: [in] The convert file descriptor id.

// byDstData: [out] The buffer to receivece the output data.

// iDstOffset: [int] The offset of the buffer.

// iDstDataSize: [int] The size of the buffer.

// Return value:

// <0: failed, ==0: packet data has not ready, >0: the size of output valid packet data.

public native static int Pop(int iCvtID,

byte[] byDstData, int iDstOffset, int iDstDataSize);

}

9. 附录

1)修改记录

版本号 修改内容 备注
1.0 初始版本
1.1 修改伪码的VideoInCtrl()函数,增加强制产生关键帧的说明。
1.2 在概述中添加结构层次图,以及注意事项。

添加关于Audio输入输出接口的说明。

升级代码样例,添加Audio的代码,优化代码结构。

1.3 1)增加视频输出回调接口说明

2)增加H265编解码格式

3)修改以前版本的描述错误

1.5 增加音频转换API接口和样例伪码
1.6 1)增加pgDevAudioOutPlaySilent()函数

2)增加pgDevAudioConvertAlloc()函数的uDevSampleRate参数的有效值说明。

1.7 1)增加pgDevVideoOutSetPixFormat()函数

2)增加PG_DEV_VIDEO_IN_FMT_I420视频输入格式

3)增加PG_DEV_VIDEO_OUT_FMT_I420视频输出格式

1.8 1)增加pgDevVideoInSetParam()函数

2)增加pgDevVideoInGetParam()函数

3)增加PG_DEV_VIDEO_IN_PARAM_E枚举

1.9 1)在PG_DEV_VIDEO_IN_PARAM_E枚举中增加PG_DEV_VIDEO_IN_PARAM_ASSEM_FRAME参数项。

2)增加PG_DEV_VIDEO_OUT_PARAM_E枚举

3)增加pgDevVideoOutSetParam()函数

4)增加pgDevVideoOutGetParam()函数

5)增加PG_DEV_AUDIO_IN_PARAM_E枚举

6)增加pgDevAudioInSetParam()函数

7)增加pgDevAudioInGetParam()函数

8)增加PG_DEV_AUDIO_OUT_PARAM_E枚举

9)增加pgDevAudioOutSetParam()函数

10)增加pgDevAudioOutGetParam()函数

11)修改代码样例

12)增加了Android系统上的JNI扩展输入输出接口的类定义,以供android平台开发时参考。

13)音频转换的采样率增加支持48000。

发表评论

邮箱地址不会被公开。 必填项已用*标注

4 + 3 =