/**************************************** * RecVideo * Obtiene los packetes y los muestra *****************************************/ int MediaBridgeSession::RecVideo() { //Coders VideoDecoder* decoder = NULL; VideoEncoder* encoder = VideoCodecFactory::CreateEncoder(VideoCodec::SORENSON); //Create new video frame RTMPVideoFrame frame(0,262143); //Set codec frame.SetVideoCodec(RTMPVideoFrame::FLV1); int width=0; int height=0; DWORD numpixels=0; Log(">RecVideo\n"); //Mientras tengamos que capturar while(receivingVideo) { ///Obtenemos el paquete RTPPacket* packet = rtpVideo.GetPacket(); //Check if (!packet) //Next continue; //Get type VideoCodec::Type type = (VideoCodec::Type)packet->GetCodec(); if ((decoder==NULL) || (type!=decoder->type)) { //Si habia uno nos lo cargamos if (decoder!=NULL) delete decoder; //Creamos uno dependiendo del tipo decoder = VideoCodecFactory::CreateDecoder(type); //Check if (!decoder) { delete(packet); continue; } } //Lo decodificamos if(!decoder->DecodePacket(packet->GetMediaData(),packet->GetMediaLength(),0,packet->GetMark())) { delete(packet); continue; } //Get mark bool mark = packet->GetMark(); //Delete packet delete(packet); //Check if it is last one if(!mark) continue; //Check size if (decoder->GetWidth()!=width || decoder->GetHeight()!=height) { //Get dimension width = decoder->GetWidth(); height = decoder->GetHeight(); //Set size numpixels = width*height*3/2; //Set also frame rate and bps encoder->SetFrameRate(25,300,500); //Set them in the encoder encoder->SetSize(width,height); } //Encode next frame VideoFrame *encoded = encoder->EncodeFrame(decoder->GetFrame(),numpixels); //Check if (!encoded) break; //Check size if (frame.GetMaxMediaSize()<encoded->GetLength()) //Not enougth space return Error("Not enought space to copy FLV encodec frame [frame:%d,encoded:%d",frame.GetMaxMediaSize(),encoded->GetLength()); //Get full frame frame.SetVideoFrame(encoded->GetData(),encoded->GetLength()); //Set buffer size frame.SetMediaSize(encoded->GetLength()); //Check type if (encoded->IsIntra()) //Set type frame.SetFrameType(RTMPVideoFrame::INTRA); else //Set type frame.SetFrameType(RTMPVideoFrame::INTER); //Let the connection set the timestamp frame.SetTimestamp(getDifTime(&first)/1000); //Send it SendMediaFrame(&frame); } //Check if (decoder) //Delete delete(decoder); //Check if (encoder) //Delete delete(encoder); Log("<RecVideo\n"); }
/**************************************** * RecVideo * Obtiene los packetes y los muestra *****************************************/ int VideoStream::RecVideo() { VideoDecoder* videoDecoder = NULL; VideoCodec::Type type; timeval before; timeval lastFPURequest; DWORD lostCount=0; DWORD frameTime = (DWORD)-1; DWORD lastSeq = RTPPacket::MaxExtSeqNum; bool waitIntra = false; Log(">RecVideo\n"); //Get now gettimeofday(&before,NULL); //Not sent FPU yet setZeroTime(&lastFPURequest); //Mientras tengamos que capturar while(receivingVideo) { //Get RTP packet RTPPacket* packet = rtp.GetPacket(); //Check if (!packet) //Next continue; //Get extended sequence number and timestamp DWORD seq = packet->GetExtSeqNum(); DWORD ts = packet->GetTimestamp(); //Get packet data BYTE* buffer = packet->GetMediaData(); DWORD size = packet->GetMediaLength(); //Get type type = (VideoCodec::Type)packet->GetCodec(); //Lost packets since last DWORD lost = 0; //If not first if (lastSeq!=RTPPacket::MaxExtSeqNum) //Calculate losts lost = seq-lastSeq-1; //Increase total lost count lostCount += lost; //Update last sequence number lastSeq = seq; //If lost some packets or still have not got an iframe if(lostCount || waitIntra) { //Check if we got listener and more than 1/2 second have elapsed from last request if (listener && getDifTime(&lastFPURequest)>minFPUPeriod) { //Debug Debug("-Requesting FPU lost %d\n",lostCount); //Reset count lostCount = 0; //Request it listener->onRequestFPU(); //Request also over rtp rtp.RequestFPU(); //Update time getUpdDifTime(&lastFPURequest); //Waiting for refresh waitIntra = true; } } //Check if it is a redundant packet if (type==VideoCodec::RED) { //Get redundant packet RTPRedundantPacket* red = (RTPRedundantPacket*)packet; //Get primary codec type = (VideoCodec::Type)red->GetPrimaryCodec(); //Check it is not ULPFEC redundant packet if (type==VideoCodec::ULPFEC) { //Delete packet delete(packet); //Skip continue; } //Update primary redundant payload buffer = red->GetPrimaryPayloadData(); size = red->GetPrimaryPayloadSize(); } //Check codecs if ((videoDecoder==NULL) || (type!=videoDecoder->type)) { //If we already got one if (videoDecoder!=NULL) //Delete it delete videoDecoder; //Create video decorder for codec videoDecoder = VideoCodecFactory::CreateDecoder(type); //Check if (videoDecoder==NULL) { Error("Error creando nuevo decodificador de video [%d]\n",type); //Delete packet delete(packet); //Next continue; } } //Check if we have lost the last packet from the previous frame by comparing both timestamps if (ts>frameTime) { Debug("-lost mark packet ts:%u frameTime:%u\n",ts,frameTime); //Try to decode what is in the buffer videoDecoder->DecodePacket(NULL,0,1,1); //Get picture BYTE *frame = videoDecoder->GetFrame(); DWORD width = videoDecoder->GetWidth(); DWORD height = videoDecoder->GetHeight(); //Check values if (frame && width && height) { //Set frame size videoOutput->SetVideoSize(width,height); //Check if muted if (!muted) //Send it videoOutput->NextFrame(frame); } } //Update frame time frameTime = ts; //Decode packet if(!videoDecoder->DecodePacket(buffer,size,lost,packet->GetMark())) { //Check if we got listener and more than 1/2 seconds have elapsed from last request if (listener && getDifTime(&lastFPURequest)>minFPUPeriod) { //Debug Log("-Requesting FPU decoder error\n"); //Reset count lostCount = 0; //Request it listener->onRequestFPU(); //Request also over rtp rtp.RequestFPU(); //Update time getUpdDifTime(&lastFPURequest); //Waiting for refresh waitIntra = true; } } //Check if it is the last packet of a frame if(packet->GetMark()) { if (videoDecoder->IsKeyFrame()) Debug("-Got Intra\n"); //No frame time yet for next frame frameTime = (DWORD)-1; //Get picture BYTE *frame = videoDecoder->GetFrame(); DWORD width = videoDecoder->GetWidth(); DWORD height = videoDecoder->GetHeight(); //Check values if (frame && width && height) { //Set frame size videoOutput->SetVideoSize(width,height); //Check if muted if (!muted) //Send it videoOutput->NextFrame(frame); } //Check if we got the waiting refresh if (waitIntra && videoDecoder->IsKeyFrame()) //Do not wait anymore waitIntra = false; } //Delete packet delete(packet); } //Delete encoder delete videoDecoder; Log("<RecVideo\n"); }