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
|
#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/modules/rtp_rtcp/source/rtp_format_h264.h"
|
||||||
#include "webrtc/system_wrappers/interface/trace.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 header = payload_data_[0];
|
||||||
uint8_t type = header & kH264NAL_TypeMask;
|
uint8_t type = header & kH264NAL_TypeMask;
|
||||||
if (payload_size_ <= max_payload_len_) {
|
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
|
// single NAL_UNIT
|
||||||
*bytes_to_send = payload_size_;
|
*bytes_to_send = payload_size_;
|
||||||
// TODO(jesup) - this doesn't work correctly for Mode 0.
|
// TODO(jesup) - this doesn't work correctly for Mode 0.
|
||||||
|
@ -13,6 +13,13 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.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/interface/rtp_payload_registry.h"
|
||||||
#include "webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.h"
|
#include "webrtc/modules/rtp_rtcp/source/rtp_format_video_generic.h"
|
||||||
#include "webrtc/modules/rtp_rtcp/source/rtp_format_h264.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;
|
RTPVideoHeaderH264* h264_header = &rtp_header->type.Video.codecHeader.H264;
|
||||||
h264_header->nalu_header = original_nal_header;
|
h264_header->nalu_header = original_nal_header;
|
||||||
h264_header->single_nalu = false;
|
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 {
|
} else {
|
||||||
|
|
||||||
// single NALU
|
// single NALU
|
||||||
payload = const_cast<uint8_t*> (payload_data);
|
payload = const_cast<uint8_t*> (payload_data);
|
||||||
payload_length = payload_data_length;
|
payload_length = payload_data_length;
|
||||||
|
Loading…
Reference in New Issue
Block a user