7月26日
#include <stdio.h>
#include "common/sample_common.h"
#include "librtsp/rtsp_demo.h"
#include "rkmedia_api.h"
#include "rkmedia_venc.h"
rtsp_demo_handle g_rtsplive = NULL;
rtsp_session_handle g_rtsp_session;
uint8_t *data;
size_t datasize;
int num =0;
//9注册输出回调函数
void my_OutCbFunc(MEDIA_BUFFER mb)
{
num++;
printf("num is %d\r\n",num);
//11推流----将数据发送到服务器---rtsp
//获取数据
data=RK_MPI_MB_GetPtr(mb);
//获取数据的大小
datasize=RK_MPI_MB_GetSize(mb);
//推流
rtsp_tx_video(g_rtsp_session, data, datasize,RK_MPI_MB_GetTimestamp(mb));
rtsp_do_event(g_rtsplive);
//释放数据缓冲区
RK_MPI_MB_ReleaseBuffer(mb);
}
int main (void)
{
//ISP配置
// rk_aiq_working_mode_t hdr_mode = RK_AIQ_WORKING_MODE_NORMAL;
// int fps = 30;
// SAMPLE_COMM_ISP_Init(0, hdr_mode, RK_FALSE, "/oem/etc/iqfiles");
// SAMPLE_COMM_ISP_Run(0);
// SAMPLE_COMM_ISP_SetFrameRate(0, fps);
//rtsp配置
g_rtsplive = create_rtsp_demo(554);
g_rtsp_session = rtsp_new_session(g_rtsplive, "/live/main_stream");
rtsp_set_video(g_rtsp_session, RTSP_CODEC_ID_VIDEO_H264, NULL, 0);
rtsp_sync_video_ts(g_rtsp_session, rtsp_get_reltime(), rtsp_get_ntptime());
//1初始化系统
RK_MPI_SYS_Init();
//3填充VI通道属性
VI_CHN_ATTR_S pstChnAttr={0};
pstChnAttr.enBufType=VI_CHN_BUF_TYPE_MMAP ; //数据传输模式 -手册
pstChnAttr.enPixFmt=IMAGE_TYPE_NV12; //图像格式 -例程
pstChnAttr.enWorkMode=VI_WORK_MODE_NORMAL; //工作模式 -例程
pstChnAttr.pcVideoNode="rkispp_scale0"; //节点路径
//V4L2摄像头开发中用到的知识 3-5
pstChnAttr.u32BufCnt=3; //缓冲区个数
pstChnAttr.u32Height=768; //图像高度
pstChnAttr.u32Width=1024; //图像宽度
//2设置VI通道属性
RK_MPI_VI_SetChnAttr(0,0,&pstChnAttr);
RK_MPI_VI_EnableChn(0,0);
//6创建编码器核心结构体
VENC_CHN_ATTR_S stVencChnAttr ={0};
stVencChnAttr.stRcAttr.enRcMode=VENC_RC_MODE_H264CBR ;
stVencChnAttr.stRcAttr.stH264Cbr.fr32DstFrameRateDen=1 ;
stVencChnAttr.stRcAttr.stH264Cbr.fr32DstFrameRateNum=30;
stVencChnAttr.stRcAttr.stH264Cbr.u32BitRate=1024*768;
//I帧间隔
stVencChnAttr.stRcAttr.stH264Cbr.u32Gop=30;
//源图像的分母
stVencChnAttr.stRcAttr.stH264Cbr.u32SrcFrameRateDen=1;
//源图像的分子
stVencChnAttr.stRcAttr.stH264Cbr.u32SrcFrameRateNum=30;
//使用的编码器
stVencChnAttr.stVencAttr.enType= RK_CODEC_TYPE_H264;
//输入图片类型
stVencChnAttr.stVencAttr.imageType=IMAGE_TYPE_NV12 ;
stVencChnAttr.stVencAttr.u32PicHeight=768;
stVencChnAttr.stVencAttr.u32PicWidth=1024;
//编码等级----选择正常
stVencChnAttr.stVencAttr.u32Profile=77;
stVencChnAttr.stVencAttr.u32VirHeight=768;
stVencChnAttr.stVencAttr.u32VirWidth=1024;
//5创建编码通道
RK_MPI_VENC_CreateChn(0,&stVencChnAttr);
//8数据来源通道
MPP_CHN_S pstChn ={0};
//推流数据来自VENC
pstChn.enModId=RK_ID_VENC;
pstChn.s32ChnId=0;//当前只有通道0
pstChn.s32DevId=0;
//7注册数据输出回调
RK_MPI_SYS_RegisterOutCb(&pstChn,my_OutCbFunc);
MPP_CHN_S pstSrcChn ={0};
pstSrcChn.enModId = RK_ID_VI;
pstSrcChn.s32ChnId=0;//当前只有通道0
pstSrcChn.s32DevId=0;
//10绑定-----将VI和VENC建立联系
RK_MPI_SYS_Bind(&pstSrcChn,&pstChn);
while(1)
{
usleep(30000);
}
RK_MPI_SYS_UnBind(&pstSrcChn,&pstChn);
RK_MPI_VENC_DestroyChn(0);
RK_MPI_VI_DisableChn(0,0);
return 0;
}
7月29日
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include "rkmedia_api.h"
#include <time.h>
int main (void)
{
//1初始化Rockchip的多媒体处理接口。
RK_MPI_SYS_Init();
AI_CHN_ATTR_S pstAttr={0};
pstAttr.enAiLayout=AI_LAYOUT_NORMAL ;
pstAttr.enSampleFormat=RK_SAMPLE_FMT_S16 ;
//
pstAttr.pcAudioNode= "plughw:1,0";
pstAttr.u32Channels= 2;
pstAttr.u32NbSamples= 1024;
pstAttr.u32SampleRate=48000;
//3音频通道属性
RK_MPI_AI_SetChnAttr(0,&pstAttr);
//4使能音频输入通道
RK_MPI_AI_EnableChn(0);
//编码2、填充音频编码通道属性
AENC_CHN_ATTR_S aencpstAttr ={0};
aencpstAttr.enCodecType= RK_CODEC_TYPE_MP3;
aencpstAttr.stAencMP3.u32Channels= 2;//编码通道
aencpstAttr.stAencMP3.u32SampleRate= 48000;//采样率
aencpstAttr.u32Bitrate= 64000;//比特率----参考的官方的
aencpstAttr.u32Quality= 1;//编码质量----参考官方的
//编码1、创建音频编码通道
RK_MPI_AENC_CreateChn(0,&aencpstAttr);
//编码3、绑定音频输入通道和音频编码通道
MPP_CHN_S pstSrcChn={0};
pstSrcChn.enModId=RK_ID_AI;
pstSrcChn.s32ChnId= 0;
pstSrcChn.s32DevId= 0;
MPP_CHN_S pstDestChn={0};
pstDestChn.enModId=RK_ID_AENC;
pstDestChn.s32ChnId= 0;
pstDestChn.s32DevId= 0;
RK_MPI_SYS_Bind(&pstSrcChn,&pstDestChn);
//5开启音频流
RK_MPI_AI_StartStream(0);
//7定义多媒体内容
MEDIA_BUFFER mb =NULL;
uint8_t *data =NULL;
size_t lenth =0;
//10打开保存的文件
//FILE *fp=fopen("./zyl_ai.pcm","w");
//编码4、换成mp3后缀
FILE *fp=fopen("./zyl_ai.mp3","w");
//通过时间结束循环
time_t begin_tim =time(NULL);
time_t end_tim;
while(1)
{
end_tim=time(NULL);
if(end_tim-begin_tim>=10)
break;
//6获取多媒体内容
//mb=RK_MPI_SYS_GetMediaBuffer(RK_ID_AI,0,-1);
//编码5、从AENC通道获取
mb=RK_MPI_SYS_GetMediaBuffer(RK_ID_AENC,0,-1);
//8从媒体缓冲区获取数据指针
data=RK_MPI_MB_GetPtr(mb);
//9获取媒体缓冲区中数据的大小。
lenth=RK_MPI_MB_GetSize(mb);
//11写入文件
fwrite(data,1,lenth,fp);
fflush(fp);
//12释放多媒体内容
RK_MPI_MB_ReleaseBuffer(mb);
}
fclose(fp);
RK_MPI_SYS_UnBind(&pstSrcChn,&pstDestChn);
RK_MPI_AI_DisableChn(0);//禁用音频输入通道。
RK_MPI_AENC_DestroyChn(0);//销毁音频编码通道。
//system("chmod 777 ./zyl_ai.pcm");
system("chmod 777 ./zyl_ai.mp3");
return 0;
}
7月30日
#include <stdio.h>
#include "sample_common.h"
#include "rkmedia_api.h"
#include "rkmedia_venc.h"
typedef struct rkMuxerHandle {
RK_U32 u32ModeIdx;
RK_U32 u32ChnIdx;
} MuxerHandle;
void myEventCbFunc(RK_VOID *pHandle, RK_VOID *event)
{
pHandle = pHandle;
event = event;
// RK_S32 s32ModeIdx = -1;
// RK_S32 s32ChnIdx = -1;
// if (pHandle) {
// MuxerHandle *pstMuxerHandle = (MuxerHandle *)pHandle;
// s32ModeIdx = (RK_S32)pstMuxerHandle->u32ModeIdx;
// s32ChnIdx = (RK_S32)pstMuxerHandle->u32ChnIdx;
// }
// if (event) {
// MUXER_EVENT_INFO_S *pstMuxerEvent = (MUXER_EVENT_INFO_S *)event;
// pstMuxerEvent = pstMuxerEvent;
// }
}
int main(void)
{
rk_aiq_working_mode_t hdr_mode = RK_AIQ_WORKING_MODE_NORMAL;
int fps = 30;
SAMPLE_COMM_ISP_Init(0, hdr_mode, RK_FALSE, "/oem/etc/iqfiles");
SAMPLE_COMM_ISP_Run(0);
SAMPLE_COMM_ISP_SetFrameRate(0, fps);
//1、初始化系统
RK_MPI_SYS_Init();
//3、填充VI通道属性
VI_CHN_ATTR_S video_pstDstChnAttr = {0};
video_pstDstChnAttr.enBufType = VI_CHN_BUF_TYPE_MMAP; //数据传输模式
video_pstDstChnAttr.enPixFmt = IMAGE_TYPE_NV12; //图像格式
video_pstDstChnAttr.enWorkMode = VI_WORK_MODE_NORMAL; //工作模式
video_pstDstChnAttr.pcVideoNode = "rkispp_scale0"; //节点路径
//V4L2摄像头开发中用到的知识 3~5
video_pstDstChnAttr.u32BufCnt = 3; //缓冲区个数
video_pstDstChnAttr.u32Height = 768; //图像宽度
video_pstDstChnAttr.u32Width = 1024; //图像高度
//2、设置VI通道属性
RK_MPI_VI_SetChnAttr(0,0,&video_pstDstChnAttr);
//4、启用VI通道
RK_MPI_VI_EnableChn(0,0);
//6、编码器核心结构体创建
VENC_CHN_ATTR_S stVencChnAttr = {0};
//选择固定码率
stVencChnAttr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBR;
//目标图像的分母
stVencChnAttr.stRcAttr.stH264Cbr.fr32DstFrameRateDen = 1;
//目标图像的分子
stVencChnAttr.stRcAttr.stH264Cbr.fr32DstFrameRateNum = 30;
//比特率 --- 图像的长*图像的宽
stVencChnAttr.stRcAttr.stH264Cbr.u32BitRate = 1024*768;
//I帧间隔
stVencChnAttr.stRcAttr.stH264Cbr.u32Gop = 30;
//源图像的分母
stVencChnAttr.stRcAttr.stH264Cbr.u32SrcFrameRateDen = 1;
//源图像的分子
stVencChnAttr.stRcAttr.stH264Cbr.u32SrcFrameRateNum = 30;
//使用的编码器
stVencChnAttr.stVencAttr.enType = RK_CODEC_TYPE_H264;
//输入图像类型
stVencChnAttr.stVencAttr.imageType = IMAGE_TYPE_NV12;
stVencChnAttr.stVencAttr.u32PicHeight = 768;
stVencChnAttr.stVencAttr.u32PicWidth = 1024;
//编码等级 --- 正常
stVencChnAttr.stVencAttr.u32Profile = 77;
stVencChnAttr.stVencAttr.u32VirHeight = 768;
stVencChnAttr.stVencAttr.u32VirWidth = 1024;
//5、创建编码通道
RK_MPI_VENC_CreateChn(0,&stVencChnAttr);
//7、数据来源通道
MPP_CHN_S video_pstDstChn = {0};
//推流数据来自VENC
video_pstDstChn.enModId = RK_ID_VENC;
video_pstDstChn.s32ChnId = 0; //当前只有通道0
video_pstDstChn.s32DevId = 0;
MPP_CHN_S video_pstSrcChn = {0};
video_pstSrcChn.enModId = RK_ID_VI;
video_pstSrcChn.s32ChnId = 0;
video_pstSrcChn.s32DevId = 0;
//8、绑定 --- 将VI和VENC建立联系
RK_MPI_SYS_Bind(&video_pstSrcChn,&video_pstDstChn);
///////////////////////////////////////
//10.音频通道属性
AI_CHN_ATTR_S pstAttr = {0};
pstAttr.enAiLayout = AI_LAYOUT_NORMAL;//正常输入类型
pstAttr.enSampleFormat = RK_SAMPLE_FMT_S16;//音频输入格式-----没有经过编码也称之为PCM
pstAttr.pcAudioNode = "plughw:1,0";//使用的声卡
pstAttr.u32Channels = 2;//通道数---双声道
pstAttr.u32NbSamples = 1152;//每帧的采样点个数 --- 常用的1024和1152,分别代表了不同的音频质量
pstAttr.u32SampleRate = 48000;//采样率
//9.设置音频输入通道属性
RK_MPI_AI_SetChnAttr(0,&pstAttr);
//11.使能音频输入通道
RK_MPI_AI_EnableChn(0);
//13、填充编码通道属性
AENC_CHN_ATTR_S aencpstAttr = {0};
//编码格式
aencpstAttr.enCodecType = RK_CODEC_TYPE_MP2;
aencpstAttr.stAencMP2.u32Channels = 2;
aencpstAttr.stAencMP2.u32SampleRate = 48000;
aencpstAttr.u32Bitrate = 64000;//比特率
aencpstAttr.u32Quality = 1;//编码质量
//12、创建音频编码通道
RK_MPI_AENC_CreateChn(0,&aencpstAttr);
//14、绑定音频输入和音频编码通道
MPP_CHN_S pstSrcChn = {0};
pstSrcChn.enModId = RK_ID_AI;
pstSrcChn.s32ChnId = 0;
pstSrcChn.s32DevId = 0;
MPP_CHN_S pstDestChn = {0};
pstDestChn.enModId = RK_ID_AENC;
pstDestChn.s32ChnId = 0;
pstDestChn.s32DevId = 0;
RK_MPI_SYS_Bind(&pstSrcChn,&pstDestChn);
//new2、合成器属性填充
MUXER_CHN_ATTR_S muxer_pstAttr = {0};
//自动分割
muxer_pstAttr.enMode = MUXER_MODE_AUTOSPLIT;
//合成后的格式
muxer_pstAttr.enType = MUXER_TYPE_MP4;
//合成器的ID
muxer_pstAttr.u32MuxerId = 0;
//自动分割相关属性
//通过时间分割
muxer_pstAttr.stSplitAttr.enSplitType = MUXER_SPLIT_TYPE_TIME;
//30秒分割一次
muxer_pstAttr.stSplitAttr.u32TimeLenSec = 30;
//命名方式 --- 自动
muxer_pstAttr.stSplitAttr.enSplitNameType = MUXER_SPLIT_NAME_TYPE_AUTO;
//自动命名的前缀
muxer_pstAttr.stSplitAttr.stNameAutoAttr.pcPrefix = "muxer_test";
//自动命名的起始下标
muxer_pstAttr.stSplitAttr.stNameAutoAttr.u16StartIdx = 1;
//视频保存的路径
muxer_pstAttr.stSplitAttr.stNameAutoAttr.pcBaseDir = "./";
//时间戳
// muxer_pstAttr.stSplitAttr.stNameAutoAttr.bTimeStampEnable = RK_TRUE;
//设置视频流参数
muxer_pstAttr.stVideoStreamParam.enCodecType = RK_CODEC_TYPE_H264;
muxer_pstAttr.stVideoStreamParam.enImageType = IMAGE_TYPE_NV12;
muxer_pstAttr.stVideoStreamParam.u16Fps = 30;
muxer_pstAttr.stVideoStreamParam.u16Level = 41; //来自官方
muxer_pstAttr.stVideoStreamParam.u16Profile = 77;
muxer_pstAttr.stVideoStreamParam.u32BitRate = 1024*768;
muxer_pstAttr.stVideoStreamParam.u32Height = 768;
muxer_pstAttr.stVideoStreamParam.u32Width = 1024;
muxer_pstAttr.stAudioStreamParam.enCodecType = RK_CODEC_TYPE_MP2;
muxer_pstAttr.stAudioStreamParam.enSampFmt = RK_SAMPLE_FMT_S16;
muxer_pstAttr.stAudioStreamParam.u32Channels = 2;
muxer_pstAttr.stAudioStreamParam.u32NbSamples = 1152;
muxer_pstAttr.stAudioStreamParam.u32SampleRate = 48000;
//new1、合成器通道使能
RK_MPI_MUXER_EnableChn(0,&muxer_pstAttr);
//new4、定义相关变量
MPP_CHN_S muxer_pstChn = {0};
muxer_pstChn.enModId = RK_ID_MUXER;
muxer_pstChn.s32ChnId = 0;
muxer_pstChn.s32DevId = 0;
MuxerHandle stMuxerHandle;
stMuxerHandle.u32ChnIdx = 0;
stMuxerHandle.u32ModeIdx = RK_ID_MUXER;
//new3、注册合成器事件回调函数
RK_MPI_SYS_RegisterEventCb(&muxer_pstChn,&stMuxerHandle,\
myEventCbFunc);
//new5、开启合成器数据流
RK_MPI_MUXER_StreamStart(0);
//new6、绑定视频VENC --- MUXER
MUXER_CHN_S muxer_video_pstDestChn = {0};
muxer_video_pstDestChn.enChnType = MUXER_CHN_TYPE_VIDEO;
muxer_video_pstDestChn.enModId = RK_ID_MUXER;
muxer_video_pstDestChn.s32ChnId = 0;
RK_MPI_MUXER_Bind(&video_pstDstChn,&muxer_video_pstDestChn);
//new7、绑定音频AENC --- MUXER
MUXER_CHN_S muxer_audio_pstDestChn = {0};
muxer_audio_pstDestChn.enChnType = MUXER_CHN_TYPE_AUDIO;
muxer_audio_pstDestChn.enModId = RK_ID_MUXER;
muxer_audio_pstDestChn.s32ChnId = 0;
RK_MPI_MUXER_Bind(&pstDestChn,&muxer_audio_pstDestChn);
int count = 0;
while(1)
{
count++;
sleep(1);
if(count == 40)
break;
}
RK_MPI_SYS_UnBind(&pstSrcChn,&pstDestChn);
RK_MPI_AI_DisableChn(0);
RK_MPI_AENC_DestroyChn(0);
RK_MPI_SYS_UnBind(&video_pstSrcChn,&video_pstDstChn);
RK_MPI_VENC_DestroyChn(0);
RK_MPI_VI_DisableChn(0,0);
SAMPLE_COMM_ISP_Stop(0);
return 0;
}