📄 vmport.cpp
字号:
#include "VMPort.h"
#include "routine.h"
int TVMPort::OpenServices(int board, int userid, const char *ip)
{
CTA_SERVICE_DESC ServDesc[2] = {0};
CTA_EVENT event;
ServDesc[0].name.svcname = "ADI";
ServDesc[0].name.svcmgrname = "ADIMGR";
ServDesc[0].mvipaddr.board = board;
ServDesc[0].mvipaddr.stream = 0;
ServDesc[0].mvipaddr.timeslot = 0;
ServDesc[0].mvipaddr.mode = 0;
ServDesc[1].name.svcname = "MSP";
ServDesc[1].name.svcmgrname = "MSPMGR";
ServDesc[0].mvipaddr.board = board;
ServDesc[1].mvipaddr.stream = 0;
ServDesc[1].mvipaddr.timeslot = 0;
ServDesc[1].mvipaddr.mode = 0;
if(ctaCreateQueue(NULL, 0, &m_quehd) != 0)
return -1;
//初始化video
if(ctaCreateContext(m_quehd, userid, "vmdemo", &m_VideoCtx.ctahd) != 0)
return -1;
if( ctaOpenServices( m_VideoCtx.ctahd, ServDesc, 2) != 0)
return -1;
ctaWaitEvent(m_quehd, &event, -1);
ShowEvent(&event);
if((event.id != CTAEVN_OPEN_SERVICES_DONE) || (event.value != CTA_REASON_FINISHED))
return -1;
//初始化audio
if(ctaCreateContext(m_quehd, userid/*使用同样的userid*/, "vmdemo", &m_AudioCtx.ctahd) != 0)
return -1;
if( ctaOpenServices( m_AudioCtx.ctahd, ServDesc, 2) != 0)
return -1;
ctaWaitEvent(m_quehd, &event, -1);
ShowEvent(&event);
if((event.id != CTAEVN_OPEN_SERVICES_DONE) || (event.value != CTA_REASON_FINISHED))
return -1;
//成功
m_board = board;
m_userid = userid;
strcpy(m_LocalIP, ip);
return 0;
}
void TVMPort::FreeRes()
{
}
bool TVMPort::StartMSP(int localport, int remoteport)
{
m_localport = localport;
m_remoteport = remoteport;
CreateVideoEp();
return true;
}
bool TVMPort::StopMSP()
{
return true;
}
bool TVMPort::CreateVideoEp()
{
m_vmstate = 0;
MSP_ENDPOINT_ADDR addr = {0};
MSP_ENDPOINT_PARAMETER parm = {0};
addr.size = sizeof MSP_ENDPOINT_ADDR;
addr.nBoard = m_board;
addr.eEpType = MSP_ENDPOINT_RTPFDX_VIDEO;
strcpy(addr.EP.RtpRtcp.SrcIpAddress, m_LocalIP);
addr.EP.RtpRtcp.nSrcPort = m_localport;
strcpy(addr.EP.RtpRtcp.DestIpAddress, m_LocalIP);
addr.EP.RtpRtcp.nDestPort = m_remoteport;
printf("\t vm(%d) video SrcPort = %d, DestPort = %d\n",
m_userid,
addr.EP.RtpRtcp.nSrcPort,
addr.EP.RtpRtcp.nDestPort
);
parm.size = sizeof(parm);
parm.eParmType = MSP_ENDPOINT_RTPFDX_VIDEO;
parm.EP.RtpRtcp.startRtcp = 0;
parm.EP.RtpRtcp.RtpTsFreq = 90000;
parm.EP.RtpRtcp.Session_bw = 64000;
parm.EP.RtpRtcp.frameQuota = 2;
parm.EP.RtpRtcp.linkEvents = 0;
parm.EP.RtpRtcp.PayloadMap.payload_id = 96;
parm.EP.RtpRtcp.PayloadMap.vocoder = 100;
parm.EP.RtpRtcp.dtmf_event_control = 0;
return 0 == mspCreateEndpoint(m_VideoCtx.ctahd, &addr, &parm, &m_VideoCtx.msphd);
}
bool TVMPort::CreateAudioEp()
{
m_vmstate++;
MSP_ENDPOINT_ADDR addr = {0};
MSP_ENDPOINT_PARAMETER parm = {0};
addr.size = sizeof MSP_ENDPOINT_ADDR;
addr.nBoard = m_board;
addr.eEpType = MSP_ENDPOINT_RTPFDX;
strcpy(addr.EP.RtpRtcp.SrcIpAddress, m_LocalIP);
addr.EP.RtpRtcp.nSrcPort = m_localport + 2;
strcpy(addr.EP.RtpRtcp.DestIpAddress, m_LocalIP);
addr.EP.RtpRtcp.nDestPort = m_remoteport + 2;
printf("\t vm(%d) audio SrcPort = %d, DestPort = %d\n",
m_userid,
addr.EP.RtpRtcp.nSrcPort,
addr.EP.RtpRtcp.nDestPort
);
parm.size = sizeof(parm);
parm.eParmType = MSP_ENDPOINT_RTPFDX;
parm.EP.RtpRtcp.startRtcp = 0;
parm.EP.RtpRtcp.RtpTsFreq = 8000;
parm.EP.RtpRtcp.Session_bw = 64000;
parm.EP.RtpRtcp.frameQuota = 2;
parm.EP.RtpRtcp.linkEvents = 0;
parm.EP.RtpRtcp.PayloadMap.payload_id = MSP_CONST_VOCODER_AMR3267;
parm.EP.RtpRtcp.PayloadMap.vocoder = MSP_CONST_VOCODER_AMR3267;
return 0 == mspCreateEndpoint(m_AudioCtx.ctahd, &addr, &parm, &m_AudioCtx.msphd);
}
void TVMPort::OnMspEvent(CTA_EVENT *pEvent)
{
switch(m_vmstate)
{
case 0:
//CreateVideoEp();
CreateAudioEp();
break;
case 1:
mspGetFilterHandle(m_VideoCtx.msphd, MSP_ENDPOINT_RTPFDX_VIDEO, &m_VideoCtx.filterhd);
mspGetFilterHandle (m_AudioCtx.msphd, MSP_ENDPOINT_RTPFDX, &m_AudioCtx.filterhd);
break;
}
}
bool TVMPort::Play3GP(char *filename)
{
m_VideoCtx.done = false;
m_AudioCtx.done = false;
FILE_INFO_DESC fileInfoDesc;
FILE_INFO_PRESENTATION *pPresentation;
FILE_INFO_STREAM_AUDIO *pStreamHeader;
BYTE FileInfo [MAX_FILE_INFO_SIZE];
int streamCount, infoSizeLeft, blockSize, i;
BYTE *pFileInfo;
DWORD ret;
if( 0 != mmOpenFile(filename, OPEN_MODE_READ, FILE_TYPE_3GP, NULL/*FILE_FORMAT_DESC */, 0/*VERBOSE_INFO_LEVEL*/, &m_mmfile))
return false;
fileInfoDesc.fileInfoSize = MAX_FILE_INFO_SIZE;
fileInfoDesc.pFileInfo = &FileInfo [0];
if( 0 != mmGetFileInfo(&m_mmfile, &fileInfoDesc))
return false;
pFileInfo = fileInfoDesc.pFileInfo;
infoSizeLeft = fileInfoDesc.fileInfoSize;
pPresentation = (FILE_INFO_PRESENTATION *)pFileInfo;
blockSize = pPresentation -> blockHeader.blkSize;
streamCount = pPresentation -> streamCount;
pFileInfo += blockSize;
infoSizeLeft -= blockSize;
for (i = 0; i < streamCount; i++)
{
blockSize = ((FILE_INFO_BLOCK_HEADER *)pFileInfo) -> blkSize;
pStreamHeader = (FILE_INFO_STREAM_AUDIO *)pFileInfo;
if (pStreamHeader -> header.streamType == STREAM_TYPE_AUDIO)
{
m_AudioCtx.codec = pStreamHeader -> header.codec;
m_AudioCtx.streamID = pStreamHeader -> header.streamID;
}
else if (pStreamHeader-> header.streamType == STREAM_TYPE_VIDEO)
{
m_VideoCtx.codec = pStreamHeader -> header.codec;
m_VideoCtx.streamID = pStreamHeader -> header.streamID;
}
if (infoSizeLeft > 0)
{
pFileInfo += blockSize;
infoSizeLeft -= blockSize;
}
}
DATA_FORMAT_DESC dataFormatDesc = {0};
DATA_FORMAT_INFO dataFormatInfo;
//open video stream
dataFormatDesc.flags |= FORMAT_FLAG_MEM_CHUNKS; //多个内存块
if( 0 != mmOpenStream(&m_mmfile, m_VideoCtx.streamID, STREAM_TYPE_VIDEO, m_VideoCtx.codec, &dataFormatDesc, &m_VideoCtx.mmstream, &dataFormatInfo))
return false;
printf("\t video estTotalStreamSize = %d minReadBufferSize = %d\n", dataFormatInfo.estTotalStreamSize, dataFormatInfo.minReadBufferSize);
unsigned videobytes;
int videoflag = 0;
ret = mmReadStream (&m_VideoCtx.mmstream, SAMPLE_COUNT_MAX, (BYTE *)m_VideoCtx.playbuffer, MAX_BUFFER_SIZE, &videobytes);
if( ret == MMERR_END_OF_STREAM)
videoflag = ADI_PLAY_LAST_BUFFER;
printf("\t videobytes = %d\n", videobytes);
//open audio stream
dataFormatDesc.flags |= FORMAT_FLAG_MEM_CHUNKS; //多个内存块
if( 0 != mmOpenStream(&m_mmfile, m_AudioCtx.streamID, STREAM_TYPE_AUDIO, m_AudioCtx.codec, &dataFormatDesc, &m_AudioCtx.mmstream, &dataFormatInfo))
return false;
printf("\t audio estTotalStreamSize = %d minReadBufferSize = %d\n", dataFormatInfo.estTotalStreamSize, dataFormatInfo.minReadBufferSize);
unsigned audiobytes;
int audioflag = 0;
ret = mmReadStream (&m_AudioCtx.mmstream, SAMPLE_COUNT_MAX, (BYTE *)m_AudioCtx.playbuffer, MAX_BUFFER_SIZE, &audiobytes);
if( ret == MMERR_END_OF_STREAM)
audioflag = ADI_PLAY_LAST_BUFFER;
printf("\t audiobytes = %d\n", audiobytes);
//video play
if( 0 != adiPlayMMAsync(m_VideoCtx.ctahd, ADI_ENCODE_NATIVE_H_263P, m_VideoCtx.playbuffer, videobytes,
videoflag,
m_VideoCtx.filterhd, NULL))
{
return false;
}
//audio play
if( 0 != adiPlayMMAsync(m_AudioCtx.ctahd, ADI_ENCODE_NATIVE_AMRNB, m_AudioCtx.playbuffer, audiobytes,
audioflag,
m_AudioCtx.filterhd, NULL) )
{
return false;
}
return true;
}
bool TVMPort::StopRP()
{
//ADI_RECORD_STATUS recordstatus;
//adiGetRecordStatus(m_VideoCtx.ctahd, &recordstatus, sizeof recordstatus );
//if(recordstatus.reason == 0) //reason = 0, mean active
adiStopRecording(m_VideoCtx.ctahd);
//ADI_PLAY_STATUS playstatus;
//adiGetPlayStatus(m_VideoCtx.ctahd, &playstatus, sizeof playstatus );
//if(playstatus.reason == 0) //reason = 0, mean active
adiStopPlaying(m_VideoCtx.ctahd);
adiStopPlaying(m_AudioCtx.ctahd);
return true;
}
bool TVMPort::ContinuePlay(CTA_EVENT *pEvent)
{
DWORD ret;
if(pEvent->ctahd == m_VideoCtx.ctahd)
{
unsigned videobytes;
int videoflag = 0;
ret = mmReadStream (&m_VideoCtx.mmstream, SAMPLE_COUNT_MAX, (BYTE *)m_VideoCtx.playbuffer, MAX_BUFFER_SIZE, &videobytes);
if( ret == MMERR_END_OF_STREAM)
videoflag = ADI_PLAY_LAST_BUFFER;
printf("\t videobytes = %d\n", videobytes);
return 0 == adiSubmitPlayBuffer(m_VideoCtx.ctahd, m_VideoCtx.playbuffer, videobytes, videoflag);
}
else if(pEvent->ctahd == m_AudioCtx.ctahd)
{
int audioflag = 0;
unsigned audiobytes;
ret = mmReadStream (&m_AudioCtx.mmstream, SAMPLE_COUNT_MAX, (BYTE *)m_AudioCtx.playbuffer, MAX_BUFFER_SIZE, &audiobytes);
if( ret == MMERR_END_OF_STREAM)
audioflag = ADI_PLAY_LAST_BUFFER;
printf("\t audiobytes = %d\n", audiobytes);
return 0 == adiSubmitPlayBuffer(m_AudioCtx.ctahd, m_AudioCtx.playbuffer, audiobytes, audioflag);
}
return false;
}
void TVMPort::OnPlayDone(CTA_EVENT *pEvent)
{
if(pEvent->ctahd == m_VideoCtx.ctahd)
m_VideoCtx.done = true;
else if(pEvent->ctahd == m_AudioCtx.ctahd)
m_AudioCtx.done = true;
if(m_VideoCtx.done && m_AudioCtx.done)
mmCloseFile(&m_mmfile);
}
void TVMPort::OnRecordDone(CTA_EVENT *pEvent)
{
OnPlayDone(pEvent);
}
bool TVMPort::Record3GP(char *filename)
{
m_VideoCtx.done = false;
m_AudioCtx.done = false;
ADI_MM_RECORD_PARMS recParms;
if( 0 != mmOpenFile (filename, OPEN_MODE_WRITE, FILE_TYPE_3GP, NULL, VERBOSE_INFO_LEVEL, &m_mmfile))
return false;
DATA_FORMAT_DESC dataFormatDesc = {0};
//video
m_VideoCtx.codec = S_CODEC_H263;
dataFormatDesc.flags |= FORMAT_FLAG_MEM_CHUNKS;
dataFormatDesc.videoLevel = 10;
dataFormatDesc.videoProfile = 0;
if( 0 != mmOpenStream(&m_mmfile, NULL, STREAM_TYPE_VIDEO, m_VideoCtx.codec, &dataFormatDesc,
&m_VideoCtx.mmstream, NULL) )
{
return false;
}
ctaGetParms (m_VideoCtx.ctahd, ADI_RECORD_PARMID, &recParms, sizeof (ADI_MM_RECORD_PARMS));
recParms.novideotime = 0;
recParms.novoicetime = 0;
recParms.videotimeout = 0;
recParms.silencetime = 0;
recParms.startonvideoIframe = 1;
if( 0 != adiRecordMMAsync(m_VideoCtx.ctahd, ADI_ENCODE_NATIVE_H_263P, m_VideoCtx.recordbuffer, MAX_BUFFER_SIZE, m_VideoCtx.filterhd, m_AudioCtx.filterhd, &recParms))
{
return false;
}
//audio
m_AudioCtx.codec = S_CODEC_AMR;
memset(&dataFormatDesc, 0 , sizeof(dataFormatDesc));
dataFormatDesc.flags |= FORMAT_FLAG_MEM_CHUNKS;
if( 0 != mmOpenStream(&m_mmfile, NULL, STREAM_TYPE_AUDIO, m_AudioCtx.codec, &dataFormatDesc,
&m_AudioCtx.mmstream, NULL) )
{
return false;
}
if( 0 != adiRecordMMAsync(m_AudioCtx.ctahd, ADI_ENCODE_NATIVE_AMRNB, m_AudioCtx.recordbuffer, MAX_BUFFER_SIZE, m_VideoCtx.filterhd, m_AudioCtx.filterhd, &recParms))
{
return false;
}
return true;
}
bool TVMPort::ContinueRecord(CTA_EVENT *pEvent)
{
printf("\t ContinueRecord\n");
unsigned byteCountRec;
switch(pEvent->id)
{
case ADIEVN_RECORD_STARTED:
if(pEvent->ctahd == m_VideoCtx.ctahd)
return 0 == adiSubmitRecordBuffer(m_VideoCtx.ctahd, m_VideoCtx.recordbuffer, MAX_BUFFER_SIZE);
else if(pEvent->ctahd == m_AudioCtx.ctahd)
return 0 == adiSubmitRecordBuffer(m_AudioCtx.ctahd, m_AudioCtx.recordbuffer, MAX_BUFFER_SIZE);
break;
case ADIEVN_RECORD_BUFFER_FULL:
if(pEvent->ctahd == m_VideoCtx.ctahd)
{
mmWriteStream(&m_VideoCtx.mmstream, (BYTE *)pEvent->buffer, pEvent->size,
NULL, &byteCountRec, NULL, NULL);
adiSubmitRecordBuffer(m_VideoCtx.ctahd, m_VideoCtx.recordbuffer, MAX_BUFFER_SIZE);
}
else if(pEvent->ctahd == m_AudioCtx.ctahd)
{
mmWriteStream(&m_AudioCtx.mmstream, (BYTE *)pEvent->buffer, pEvent->size,
NULL, &byteCountRec, NULL, NULL);
adiSubmitRecordBuffer(m_AudioCtx.ctahd, m_AudioCtx.recordbuffer, MAX_BUFFER_SIZE);
}
break;
}
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -