int MediaBridgeSession::SendAudio() { AudioCodec::Type rtmpAudioCodec; RTPPacket packet(MediaFrame::Audio,rtpAudioCodec,rtpAudioCodec); QWORD lastAudioTs = 0; DWORD frameTime=0; Log(">SendAudio\n"); //While sending audio while (sendingAudio) { //Wait for next audio if (!audioFrames.Wait(0)) //Check again continue; //Get audio grame RTMPAudioFrame* audio = audioFrames.Pop(); //check if (!audio) //Again continue; //Get timestamp QWORD ts = audio->GetTimestamp(); //Get delay QWORD diff = 0; //If it is the first frame if (lastAudioTs) //Calculate it diff = ts - lastAudioTs; //Check diff if (diff<40) //Set it to only one frame of 20 ms diff = 20; //Set the last audio timestamp lastAudioTs = ts; //Get codec type switch(audio->GetAudioCodec()) { case RTMPAudioFrame::SPEEX: //Set codec rtmpAudioCodec = AudioCodec::SPEEX16; break; case RTMPAudioFrame::NELLY: //Set codec type rtmpAudioCodec = AudioCodec::NELLY11; break; default: continue; } //Check rtp type if (rtpAudioCodec!=rtmpAudioCodec) { BYTE rtp[MTU+SRTP_MAX_TRAILER_LEN] ZEROALIGNEDTO32; DWORD rtpSize = RTPPAYLOADSIZE; DWORD rtpLen = 0; SWORD raw[512]; DWORD rawSize = 512; DWORD rawLen = 0; //Check if we have a decoder if (!rtmpAudioDecoder || rtmpAudioDecoder->type!=rtmpAudioCodec) { //Check if (rtmpAudioDecoder) //Delete old one delete(rtmpAudioDecoder); //Create new one rtmpAudioDecoder = AudioCodecFactory::CreateDecoder(rtmpAudioCodec); } //Get data BYTE *data = audio->GetMediaData(); //Get size DWORD size = audio->GetMediaSize(); //Decode it until no frame is found while ((rawLen = rtmpAudioDecoder->Decode(data,size,raw,rawSize))>0) { //Check size if (rawLen>0) { //Rencode ig rtpLen = rtpAudioEncoder->Encode(raw,rawLen,rtp,rtpSize); //Send if (rtpAudioCodec==AudioCodec::SPEEX16) { //Send rtp packet //FIX!! rtpAudio.SendAudioPacket(rtp,rtpLen,diff*16); } else { //Send rtp packet //FIX!! rtpAudio.SendAudioPacket(rtp,rtpLen,diff*8); } } //Set diff diff = 20; //Remove size size = 0; } } else { //Set data packet.SetPayload(audio->GetMediaData(),audio->GetMediaSize()); //Send rtp packet rtpAudio.SendPacket(packet); } //Delete audio delete(audio); } Log("<SendAudio\n"); return 1; }
/**************************************** * RecAudio * Obtiene los packetes y los muestra *****************************************/ int MediaBridgeSession::RecAudio() { DWORD firstAudio = 0; DWORD timeStamp=0; DWORD firstTS = 0; SWORD raw[512]; DWORD rawSize = 512; DWORD rawLen; //Create new audio frame RTMPAudioFrame *audio = new RTMPAudioFrame(0,RTPPAYLOADSIZE); Log(">RecAudio\n"); //Mientras tengamos que capturar while(receivingAudio) { //Obtenemos el paquete RTPPacket *packet = rtpAudio.GetPacket(); //Check if (!packet) //Next continue; //Get type AudioCodec::Type codec = (AudioCodec::Type)packet->GetCodec(); //Check rtp type if (codec==AudioCodec::SPEEX16) { //TODO!!!! } //Check if we have a decoder if (!rtpAudioDecoder || rtpAudioDecoder->type!=codec) { //Check if (rtpAudioDecoder) //Delete old one delete(rtpAudioDecoder); //Create new one rtpAudioDecoder = AudioCodecFactory::CreateDecoder(codec); } //Decode it rawLen = rtpAudioDecoder->Decode(packet->GetMediaData(),packet->GetMediaLength(),raw,rawSize); //Delete packet delete(packet); //Rencode it DWORD len; while((len=rtmpAudioEncoder->Encode(raw,rawLen,audio->GetMediaData(),audio->GetMaxMediaSize()))>0) { //REset rawLen = 0; //Set length audio->SetMediaSize(len); switch(rtmpAudioEncoder->type) { case AudioCodec::SPEEX16: //Set RTMP data audio->SetAudioCodec(RTMPAudioFrame::SPEEX); audio->SetSoundRate(RTMPAudioFrame::RATE11khz); audio->SetSamples16Bits(1); audio->SetStereo(0); break; case AudioCodec::NELLY8: //Set RTMP data audio->SetAudioCodec(RTMPAudioFrame::NELLY8khz); audio->SetSoundRate(RTMPAudioFrame::RATE11khz); audio->SetSamples16Bits(1); audio->SetStereo(0); break; case AudioCodec::NELLY11: //Set RTMP data audio->SetAudioCodec(RTMPAudioFrame::NELLY); audio->SetSoundRate(RTMPAudioFrame::RATE11khz); audio->SetSamples16Bits(1); audio->SetStereo(0); break; } //If it is first if (!firstTS) { //Get first audio time firstAudio = getDifTime(&first)/1000; //It is first firstTS = timeStamp; } DWORD ts = firstAudio +(timeStamp-firstTS)/8; //Set timestamp audio->SetTimestamp(ts); //Send packet SendMediaFrame(audio); } } //Check if (audio) //Delete it delete(audio); Log("<RecAudio\n"); }
void RTMPMP4Stream::onMediaFrame(MediaFrame &media) { //Depending on the media type switch (media.GetType()) { case MediaFrame::Audio: { //Create rtmp frame RTMPAudioFrame *frame = new RTMPAudioFrame(0,512); //Get audio frame AudioFrame& audio = (AudioFrame&)media; //Check codec switch(audio.GetCodec()) { case AudioCodec::PCMA: case AudioCodec::PCMU: { WORD raw[512]; DWORD rawsize = 512; //Decode audio frame DWORD rawlen = decoder->Decode(audio.GetData(),audio.GetLength(),raw,rawsize); //Encode frame DWORD len = encoder->Encode(raw,rawlen,frame->GetMediaData(),frame->GetMaxMediaSize()); //Set length frame->SetMediaSize(len); //Set type frame->SetAudioCodec(RTMPAudioFrame::SPEEX); frame->SetSoundRate(RTMPAudioFrame::RATE11khz); frame->SetSamples16Bits(1); frame->SetStereo(0); //Set timestamp frame->SetTimestamp(audio.GetTimeStamp()/8); break; } default: //Not supported return; } //Send it PlayMediaFrame(frame); } break; case MediaFrame::Video: { //Get video frame VideoFrame& video = (VideoFrame&)media; //Create rtmp frame RTMPVideoFrame *frame = new RTMPVideoFrame(video.GetTimeStamp()/90,video.GetLength()); //Check codec switch(video.GetCodec()) { case VideoCodec::H263_1996: case VideoCodec::H263_1998: #ifdef FLV1PARSER { //Create FLV1parser in case we need it flv1Parser *parser = new flv1Parser(frame->GetMediaData(),frame->GetMaxMediaSize()); //Proccess if (!parser->FrameFromH263(video.GetData(),video.GetLength())) throw new std::exception(); //Set lengtht frame->SetMediaSize(parser->GetSize()); //If it is intra if (video.IsIntra()) //Set type frame->SetFrameType(RTMPVideoFrame::INTRA); else //Set type frame->SetFrameType(RTMPVideoFrame::INTER); //Set type frame->SetVideoCodec(RTMPVideoFrame::FLV1); } #endif break; case VideoCodec::H264: { //Set Codec frame->SetVideoCodec(RTMPVideoFrame::AVC); //If it is intra if (video.IsIntra()) { //Set type frame->SetFrameType(RTMPVideoFrame::INTRA); //If we have one if (desc) { //Create the fraame RTMPVideoFrame fdesc(frame->GetTimestamp(),desc); //Play it PlayMediaFrame(&fdesc); } } else { //Set type frame->SetFrameType(RTMPVideoFrame::INTER); } //Set NALU type frame->SetAVCType(1); //Set no delay frame->SetAVCTS(0); //Set Data frame->SetVideoFrame(video.GetData(),video.GetLength()); break; } default: //Not supported return; } //Send it PlayMediaFrame(frame); //Delete it delete(frame); } break; } }