mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1036049: Support H.264 STAP-A depacketization in webrtc r=ehugg
This commit is contained in:
parent
046773aaca
commit
cc394c3799
@ -10,6 +10,13 @@
|
||||
|
||||
#include <string.h> // memcpy
|
||||
|
||||
#ifdef WIN32
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
#ifdef WEBRTC_LINUX
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#include "webrtc/modules/rtp_rtcp/source/rtp_format_h264.h"
|
||||
#include "webrtc/system_wrappers/interface/trace.h"
|
||||
|
||||
@ -55,6 +62,29 @@ int RtpFormatH264::NextPacket(uint8_t* buffer,
|
||||
uint8_t header = payload_data_[0];
|
||||
uint8_t type = header & kH264NAL_TypeMask;
|
||||
if (payload_size_ <= max_payload_len_) {
|
||||
//#define TEST_STAP_A
|
||||
#ifdef TEST_STAP_A
|
||||
static uint8_t sps_buffer[256];
|
||||
static uint32_t sps_size;
|
||||
if (type == kH264NALU_SPS) {
|
||||
|
||||
sps_buffer[0] = kH264NALU_STAPA;
|
||||
*(reinterpret_cast<uint16_t*>(&sps_buffer[1])) = htons(payload_size_); // include NAL byte
|
||||
memcpy(&sps_buffer[1 + sizeof(uint16_t)], payload_data_, payload_size_);
|
||||
sps_size = 1 + sizeof(uint16_t) + payload_size_;
|
||||
*bytes_to_send = 0;
|
||||
return -1;
|
||||
} else if (type == kH264NALU_PPS && sps_size != 0) {
|
||||
// Send a STAP-A of SPS/PPS
|
||||
*(reinterpret_cast<uint16_t*>(&sps_buffer[sps_size])) = htons(payload_size_);
|
||||
memcpy(&sps_buffer[sps_size + sizeof(uint16_t)], payload_data_, payload_size_);
|
||||
memcpy(buffer, sps_buffer, sps_size + 2 + payload_size_);
|
||||
*bytes_to_send = sps_size + 2 + payload_size_;
|
||||
sps_size = 0;
|
||||
*last_packet = false;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
// single NAL_UNIT
|
||||
*bytes_to_send = payload_size_;
|
||||
// TODO(jesup) - this doesn't work correctly for Mode 0.
|
||||
|
@ -13,6 +13,13 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
#ifdef WEBRTC_LINUX
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h"
|
||||
#include "webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.h"
|
||||
#include "webrtc/modules/rtp_rtcp/source/rtp_format_h264.h"
|
||||
@ -265,7 +272,55 @@ int32_t RTPReceiverVideo::ReceiveH264Codec(WebRtcRTPHeader* rtp_header,
|
||||
RTPVideoHeaderH264* h264_header = &rtp_header->type.Video.codecHeader.H264;
|
||||
h264_header->nalu_header = original_nal_header;
|
||||
h264_header->single_nalu = false;
|
||||
|
||||
} else if (nal_type == RtpFormatH264::kH264NALU_STAPA) {
|
||||
|
||||
payload = const_cast<uint8_t*> (payload_data) +
|
||||
RtpFormatH264::kH264NALHeaderLengthInBytes;
|
||||
size_t size = payload_data_length -
|
||||
RtpFormatH264::kH264NALHeaderLengthInBytes;
|
||||
uint32_t timestamp = rtp_header->header.timestamp;
|
||||
rtp_header->type.Video.codec = kRtpVideoH264;
|
||||
rtp_header->type.Video.isFirstPacket = true;
|
||||
RTPVideoHeaderH264* h264_header = &rtp_header->type.Video.codecHeader.H264;
|
||||
h264_header->single_nalu = true;
|
||||
|
||||
while (size > 0) {
|
||||
payload_length = ntohs(*(reinterpret_cast<uint16_t*>(payload)));
|
||||
// payload_length includes the NAL type byte
|
||||
payload += sizeof(uint16_t); // points to NAL byte and then N bytes of NAL data
|
||||
h264_header->nalu_header = payload[0];
|
||||
switch (*payload & RtpFormatH264::kH264NAL_TypeMask) {
|
||||
case RtpFormatH264::kH264NALU_SPS:
|
||||
// TODO(jesup): Evil hack. see below
|
||||
rtp_header->header.timestamp = timestamp - 20;
|
||||
rtp_header->frameType = kVideoFrameKey;
|
||||
break;
|
||||
case RtpFormatH264::kH264NALU_PPS:
|
||||
// TODO(jesup): Evil hack. see below
|
||||
rtp_header->header.timestamp = timestamp - 10;
|
||||
rtp_header->frameType = kVideoFrameKey;
|
||||
break;
|
||||
case RtpFormatH264::kH264NALU_IDR:
|
||||
rtp_header->frameType = kVideoFrameKey;
|
||||
break;
|
||||
default:
|
||||
rtp_header->frameType = kVideoFrameDelta;
|
||||
break;
|
||||
}
|
||||
if (data_callback_->OnReceivedPayloadData(payload,
|
||||
payload_length,
|
||||
rtp_header) != 0) {
|
||||
return -1;
|
||||
}
|
||||
payload += payload_length;
|
||||
assert(size >= sizeof(uint16_t) + payload_length);
|
||||
size -= sizeof(uint16_t) + payload_length;
|
||||
}
|
||||
return 0;
|
||||
|
||||
} else {
|
||||
|
||||
// single NALU
|
||||
payload = const_cast<uint8_t*> (payload_data);
|
||||
payload_length = payload_data_length;
|
||||
|
Loading…
Reference in New Issue
Block a user