bool MultiConf::AddBroadcastReceiver(RTMPStream *receiver) { broadcast.AddReceiver(receiver); Participants::iterator itBroadcaster = participants.find(m_CurrentBroadCaster); if(itBroadcaster != participants.end()) { RTPParticipant *broadCaster = (RTPParticipant*)itBroadcaster->second; Log("Send idr packet to newly broadcast reciever\n"); IDRPacketSize idrPacketSize = broadCaster->GetIdrPacketSize(); IDRPacket idrPacket = broadCaster->GetIdrPacket(); DWORD currentTimeStamp = broadCaster->GetCurrentTimestamp(); size_t packetSize = idrPacket.size(); //Crete desc frame RTMPVideoFrame frameDesc(0,2048); //Send frameDesc.SetTimestamp(currentTimeStamp); //Set type frameDesc.SetVideoCodec(RTMPVideoFrame::AVC); //Set type frameDesc.SetFrameType(RTMPVideoFrame::INTRA); //Set NALU type frameDesc.SetAVCType(0); //Set no delay frameDesc.SetAVCTS(0); //Create description AVCDescriptor desc; //Set values desc.SetConfigurationVersion(1); //desc.SetAVCProfileIndication(0x42); //desc.SetProfileCompatibility(0x80); //desc.SetAVCLevelIndication(0x14); //desc.SetAVCProfileIndication(idrPacket[0][1]); //desc.SetProfileCompatibility(idrPacket[0][2]); //desc.SetAVCLevelIndication(idrPacket[0][3]); desc.SetAVCProfileIndication(0x64); desc.SetProfileCompatibility(0x00); desc.SetAVCLevelIndication(0x28); desc.SetNALUnitLength(3); desc.AddSequenceParameterSet(idrPacket[0],idrPacketSize[0]); desc.AddPictureParameterSet(idrPacket[1],idrPacketSize[1]); //Serialize DWORD len = desc.Serialize(frameDesc.GetMediaData(),frameDesc.GetMaxMediaSize()); //Set size frameDesc.SetMediaSize(len); //broadcast.OnPublishedFrame(0, &frameDesc); receiver->PlayMediaFrame(&frameDesc); frameDesc.Dump(); RTMPVideoFrame frame(0,65535); //Set codec frame.SetVideoCodec(RTMPVideoFrame::AVC); //Set NALU type frame.SetAVCType(1); //Set no delay frame.SetAVCTS(0); frame.SetTimestamp(currentTimeStamp); frame.SetFrameType(RTMPVideoFrame::INTRA); VideoFrame *videoFrame; RTPDepacketizer *depacketizer = RTPDepacketizer::Create( MediaFrame::Video, VideoCodec::H264); for(int i = 0; i < packetSize; i++) { BYTE *packet = idrPacket[i]; int packet_size = idrPacketSize[i]; videoFrame = (VideoFrame *)depacketizer->AddPayload(packet,packet_size); } frame.SetVideoFrame(videoFrame->GetData(), videoFrame->GetLength()); receiver->PlayMediaFrame(&frame); frame.Dump(); delete depacketizer; } return true; }
AVCDescriptor* MP4Streamer::GetAVCDescriptor() { uint8_t **sequenceHeader; uint8_t **pictureHeader; uint32_t *pictureHeaderSize; uint32_t *sequenceHeaderSize; uint32_t i; uint8_t profile, level; uint32_t len; //Check video if (!video || video->codec!=VideoCodec::H264) //Nothing return NULL; //Create descriptor AVCDescriptor* desc = new AVCDescriptor(); //Set them desc->SetConfigurationVersion(0x01); desc->SetAVCProfileIndication(profile); desc->SetProfileCompatibility(0x00); desc->SetAVCLevelIndication(level); //Set nalu length MP4GetTrackH264LengthSize(video->mp4, video->track, &len); //Set it desc->SetNALUnitLength(len-1); // Get SEI informaMP4GetTrackH264SeqPictHeaderstion MP4GetTrackH264SeqPictHeaders(video->mp4, video->track, &sequenceHeader, &sequenceHeaderSize, &pictureHeader, &pictureHeaderSize); // Send sequence headers i=0; // Check we have sequence header if (sequenceHeader) { // Loop array while(sequenceHeader[i] && sequenceHeaderSize[i]) { //Append sequence desc->AddSequenceParameterSet(sequenceHeader[i],sequenceHeaderSize[i]); //Update values based on the ones in SQS desc->SetAVCProfileIndication(sequenceHeader[i][1]); desc->SetProfileCompatibility(sequenceHeader[i][2]); desc->SetAVCLevelIndication(sequenceHeader[i][3]); //inc i++; } } // Send picture headers i=0; // Check we have picture header if (pictureHeader) { // Loop array while(pictureHeader[i] && pictureHeaderSize[i]) { //Append sequence desc->AddPictureParameterSet(pictureHeader[i],pictureHeaderSize[i]); //inc i++; } } // Free data if (pictureHeader) free(pictureHeader); if (sequenceHeader) free(sequenceHeader); if (sequenceHeaderSize) free(sequenceHeaderSize); if (pictureHeaderSize) free(pictureHeaderSize); return desc; }