void VideoEncCallback::TransmitFrame(VideoData& frame) { NalHeader* nalHdr = NULL; bool gotFrame = false; m_FrameCnt++; PACKET_DBG("From encoder: Frame length %d bytes, frame_cnt: %d", frame.Size(), m_FrameCnt); // Transmit SPS, PPS and IDR-frame in the same access unit if (Configuration::GetCfg()->GetIntVal("SendPacketsFromAnxbFile") || Configuration::GetCfg()->GetIntVal("SendPacketsFromPcapFile")) { gotFrame = true; } else { nalHdr = (NalHeader *)(frame.Data() + 4); if (nalHdr->GetType() >= NALU_SLICE && nalHdr->GetType() <= NALU_SLICE_IDR) { gotFrame = true; } else { gotFrame = false; } } if (Configuration::GetCfg()->GetIntVal("SendPacketsFromPcapFile")) { // Sending data from pcap file, already packetized for RTP m_pSend.m_pSendCallback.TransportSendRTPPacket(frame.Data(), frame.Size()); } else { if (Configuration::GetCfg()->GetIntVal("DumpSendAnxbPackets")) { m_pSend.m_pSendAnxbDump->StorePacket(frame.Data(), frame.Size()); } if (m_pSend.m_pSendCallback.GetPayloadFmt() == SkypeVideoRTPInterface::FORMAT_FRAMES) { m_pSend.m_pSendCallback.TransportSendFrame(frame); } else { m_pSend.m_AnxbToRtp.AnxbFrameToRtp(frame.Data(), frame.Size(), frame.GetTimestamp(), gotFrame); } } }
void H264RtpToAnxb::RtpToAnxbFrame(const uint8_t *buffer, uint32_t bufLen) { rtph *rtpHdr = (rtph *) buffer; NalHeader *nalHdr = (NalHeader *) rtpHdr->GetDataPtr(); int nalLen = bufLen - sizeof(rtph); if (nalHdr->GetType() >= NALU_SLICE && nalHdr->GetType() <= NALU_FILLER) { VDBG("process packet - single nal unit"); //single nal unit AddNalToAnxbBuf((uint8_t *)nalHdr, nalLen, NULL, false); } else if (nalHdr->GetType() == NALU_STAP_A) { //stap-A uint16_t stapaLen; uint8_t *nalDataPtr; VDBG("process packet - stap-A"); nalDataPtr = nalHdr->GetDataPtr(); nalLen -= sizeof(NalHeader); while (nalLen > 0) { uint16_t tmp; ((uint8_t*)&tmp)[0] = nalDataPtr[0]; ((uint8_t*)&tmp)[1] = nalDataPtr[1]; stapaLen = ntohs(tmp); nalDataPtr += sizeof(stapaLen); AddNalToAnxbBuf(nalDataPtr, stapaLen, NULL, false); VDBG("found nal: %d", stapaLen); nalLen -= sizeof(stapaLen) + stapaLen; nalDataPtr += stapaLen; } } else if (nalHdr->GetType() == NALU_FU_A) { // FU-A VDBG("process packet - FU-A"); FUAHeader *fuaHdr = (FUAHeader *)nalHdr; if (fuaHdr->GetS()) { // start bit set NalHeader rebuiltNalHdr; rebuiltNalHdr.Reset(); rebuiltNalHdr.SetNri(fuaHdr->GetNri()); rebuiltNalHdr.SetType(fuaHdr->GetNalType()); AddNalToAnxbBuf(fuaHdr->GetDataPtr(), nalLen - sizeof(FUAHeader), &rebuiltNalHdr, false); } else { AddNalToAnxbBuf(fuaHdr->GetDataPtr(), nalLen - sizeof(FUAHeader), NULL, true); } } else { ERROR("process packet - UNABLE TO GET PACKET TYPE"); } if(rtpHdr->GetMarker()) { if (anxbFrameCb) { int timestamp = TIMESTAMP_RTP90KHZ_TO_MS(rtpHdr->GetTimestamp(), lastTimestampRtp, accumulator); anxbFrameCb->TransmitAnxbFrame(anxbPacketBuf, anxbPacketBufUsed, timestamp); } anxbPacketBufUsed = 0; } }