Skip to content
This repository was archived by the owner on Oct 25, 2024. It is now read-only.

Commit e76c6d4

Browse files
taste1981Duan, Xiande
authored andcommitted
Re-enabling hevc on MCU webrtc stack
Change-Id: I6ca50accceb754e8bc537a88c09c1feec1023ded Reviewed-on: https://git-ccr-1.devtools.intel.com/gerrit/63755 Reviewed-by: Dai, Jianhui J <[email protected]> Reviewed-by: Duan, Xiande <[email protected]> Tested-by: Duan, Xiande <[email protected]>
1 parent 2cc5ed2 commit e76c6d4

21 files changed

+1001
-7
lines changed

webrtc/api/video_codecs/video_encoder.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ class EncodedImageCallback {
6767
class VideoEncoder {
6868
public:
6969
enum EncoderType {
70+
#ifndef DISABLE_H265
71+
kH265,
72+
#endif
7073
kH264,
7174
kVp8,
7275
kVp9,
@@ -95,7 +98,9 @@ class VideoEncoder {
9598
static VideoCodecVP8 GetDefaultVp8Settings();
9699
static VideoCodecVP9 GetDefaultVp9Settings();
97100
static VideoCodecH264 GetDefaultH264Settings();
98-
101+
#ifndef DISABLE_H265
102+
static VideoCodecH265 GetDefaultH265Settings();
103+
#endif
99104
virtual ~VideoEncoder() {}
100105

101106
// Initialize the encoder with the information from the codecSettings

webrtc/common_types.cc

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,24 @@ const VideoCodecH264& VideoCodec::H264() const {
9595
return codec_specific_.H264;
9696
}
9797

98+
#ifndef DISABLE_H265
99+
VideoCodecH265* VideoCodec::H265() {
100+
RTC_DCHECK_EQ(codecType, kVideoCodecH265);
101+
return &codec_specific_.H265;
102+
}
103+
104+
const VideoCodecH265& VideoCodec::H265() const {
105+
RTC_DCHECK_EQ(codecType, kVideoCodecH265);
106+
return codec_specific_.H265;
107+
}
108+
#endif
109+
98110
static const char* kPayloadNameVp8 = "VP8";
99111
static const char* kPayloadNameVp9 = "VP9";
100112
static const char* kPayloadNameH264 = "H264";
113+
#ifndef DISABLE_H265
114+
static const char* kPayloadNameH265 = "H265";
115+
#endif
101116
static const char* kPayloadNameI420 = "I420";
102117
static const char* kPayloadNameRED = "RED";
103118
static const char* kPayloadNameULPFEC = "ULPFEC";
@@ -115,6 +130,10 @@ rtc::Optional<const char*> CodecTypeToPayloadName(VideoCodecType type) {
115130
return rtc::Optional<const char*>(kPayloadNameVp9);
116131
case kVideoCodecH264:
117132
return rtc::Optional<const char*>(kPayloadNameH264);
133+
#ifndef DISABLE_H265
134+
case kVideoCodecH265:
135+
return rtc::Optional<const char*>(kPayloadNameH265);
136+
#endif
118137
case kVideoCodecI420:
119138
return rtc::Optional<const char*>(kPayloadNameI420);
120139
case kVideoCodecRED:
@@ -135,6 +154,10 @@ rtc::Optional<VideoCodecType> PayloadNameToCodecType(const std::string& name) {
135154
return rtc::Optional<VideoCodecType>(kVideoCodecVP9);
136155
if (CodecNamesEq(name.c_str(), kPayloadNameH264))
137156
return rtc::Optional<VideoCodecType>(kVideoCodecH264);
157+
#ifndef DISABLE_H265
158+
if (CodecNamesEq(name.c_str(), kPayloadNameH265))
159+
return rtc::Optional<VideoCodecType>(kVideoCodecH265);
160+
#endif
138161
if (CodecNamesEq(name.c_str(), kPayloadNameI420))
139162
return rtc::Optional<VideoCodecType>(kVideoCodecI420);
140163
if (CodecNamesEq(name.c_str(), kPayloadNameRED))

webrtc/common_types.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -511,12 +511,25 @@ struct VideoCodecH264 {
511511
size_t ppsLen;
512512
H264::Profile profile;
513513
};
514+
#ifndef DISABLE_H265
515+
struct VideoCodecH265 {
516+
bool frameDroppingOn;
517+
int keyFrameInterval;
518+
const uint8_t* spsData;
519+
size_t spsLen;
520+
const uint8_t* ppsData;
521+
size_t ppsLen;
522+
};
523+
#endif
514524

515525
// Video codec types
516526
enum VideoCodecType {
517527
kVideoCodecVP8,
518528
kVideoCodecVP9,
519529
kVideoCodecH264,
530+
#ifndef DISABLE_H265
531+
kVideoCodecH265,
532+
#endif
520533
kVideoCodecI420,
521534
kVideoCodecRED,
522535
kVideoCodecULPFEC,
@@ -533,6 +546,9 @@ union VideoCodecUnion {
533546
VideoCodecVP8 VP8;
534547
VideoCodecVP9 VP9;
535548
VideoCodecH264 H264;
549+
#ifndef DISABLE_H265
550+
VideoCodecH265 H265;
551+
#endif
536552
};
537553

538554
// Simulcast is when the same stream is encoded multiple times with different
@@ -597,7 +613,10 @@ class VideoCodec {
597613
const VideoCodecVP9& VP9() const;
598614
VideoCodecH264* H264();
599615
const VideoCodecH264& H264() const;
600-
616+
#ifndef DISABLE_H265
617+
VideoCodecH265* H265();
618+
const VideoCodecH265& H265() const;
619+
#endif
601620
private:
602621
// TODO(hta): Consider replacing the union with a pointer type.
603622
// This will allow removing the VideoCodec* types from this file.

webrtc/common_video/video_frame.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ size_t EncodedImage::GetBufferPaddingBytes(VideoCodecType codec_type) {
3030
return 0;
3131
case kVideoCodecH264:
3232
return kBufferPaddingBytesH264;
33+
#ifndef DISABLE_H265
34+
case kVideoCodecH265:
35+
return 0;
36+
#endif
3337
case kVideoCodecI420:
3438
case kVideoCodecRED:
3539
case kVideoCodecULPFEC:

webrtc/media/base/mediaconstants.cc

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,23 @@ const char kComfortNoiseCodecName[] = "CN";
101101
const char kVp8CodecName[] = "VP8";
102102
const char kVp9CodecName[] = "VP9";
103103
const char kH264CodecName[] = "H264";
104-
104+
#ifndef DISABLE_H265
105+
const char kH265CodecName[] = "H265";
106+
#endif
105107
// RFC 6184 RTP Payload Format for H.264 video
106108
const char kH264FmtpProfileLevelId[] = "profile-level-id";
107109
const char kH264FmtpLevelAsymmetryAllowed[] = "level-asymmetry-allowed";
108110
const char kH264FmtpPacketizationMode[] = "packetization-mode";
109111
const char kH264FmtpSpropParameterSets[] = "sprop-parameter-sets";
110112
const char kH264ProfileLevelConstrainedBaseline[] = "42e01f";
111113

114+
#ifndef DISABLE_H265
115+
// RFC 7798 RTP Payload Format for H.265 video
116+
const char kH265FmtpProfileSpace[] = "profile-space";
117+
const char kH265FmtpProfileId[] = "profile-id";
118+
const char kH265FmtpTierFlag[] = "tier-flag";
119+
const char kH265FmtpLevelId[] = "level-id";
120+
#endif
121+
112122
const int kDefaultVideoMaxFramerate = 60;
113123
} // namespace cricket

webrtc/modules/include/module_common_types.h

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,20 @@
2929

3030
namespace webrtc {
3131

32+
#ifndef DISABLE_H265
33+
// H265 packtization types we support: single, aggregated, and fragmented.
34+
enum H265PacketizationTypes {
35+
kH265SingleNalu,
36+
kH265AP,
37+
kH265FU,
38+
};
39+
40+
struct RTPVideoHeaderH265 {
41+
uint8_t nalu_type;
42+
H265PacketizationTypes packetization_type;
43+
};
44+
#endif
45+
3246
struct RTPAudioHeader {
3347
uint8_t numEnergy; // number of valid entries in arrOfEnergy
3448
uint8_t arrOfEnergy[kRtpCsrcSize]; // one energy byte (0-9) per channel
@@ -40,14 +54,20 @@ union RTPVideoTypeHeader {
4054
RTPVideoHeaderVP8 VP8;
4155
RTPVideoHeaderVP9 VP9;
4256
RTPVideoHeaderH264 H264;
57+
#ifndef DISABLE_H265
58+
RTPVideoHeaderH265 H265;
59+
#endif
4360
};
4461

4562
enum RtpVideoCodecTypes {
4663
kRtpVideoNone,
4764
kRtpVideoGeneric,
4865
kRtpVideoVp8,
4966
kRtpVideoVp9,
50-
kRtpVideoH264
67+
kRtpVideoH264,
68+
#ifndef DISABLE_H265
69+
kRtpVideoH265
70+
#endif
5171
};
5272
// Since RTPVideoHeader is used as a member of a union, it can't have a
5373
// non-trivial default constructor.

webrtc/modules/rtp_rtcp/BUILD.gn

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ rtc_static_library("rtp_rtcp") {
102102
"source/rtp_format.h",
103103
"source/rtp_format_h264.cc",
104104
"source/rtp_format_h264.h",
105+
"source/h265_sps_parser.cc",
106+
"source/h265_sps_parser.h",
107+
"source/rtp_format_h265.cc",
108+
"source/rtp_format_h265.h",
105109
"source/rtp_format_video_generic.cc",
106110
"source/rtp_format_video_generic.h",
107111
"source/rtp_format_vp8.cc",
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
/*
2+
* Intel License
3+
*/
4+
5+
#include "webrtc/modules/rtp_rtcp/source/h265_sps_parser.h"
6+
7+
#include "webrtc/base/bitbuffer.h"
8+
#include "webrtc/base/bytebuffer.h"
9+
#include "webrtc/base/logging.h"
10+
11+
#include <vector>
12+
13+
#define RETURN_FALSE_ON_FAIL(x) \
14+
if (!(x)) { \
15+
return false; \
16+
}
17+
18+
namespace webrtc {
19+
20+
H265SpsParser::H265SpsParser(const uint8_t* sps, size_t byte_length)
21+
: sps_(sps), byte_length_(byte_length), width_(0), height_(0) {
22+
}
23+
24+
bool H265SpsParser::Parse() {
25+
// General note: this is based off the 04/2015 version of the H.265 standard.
26+
// You can find it on this page:
27+
// http://www.itu.int/rec/T-REC-H.265
28+
29+
const char* sps_bytes = reinterpret_cast<const char*>(sps_);
30+
// First, parse out rbsp, which is basically the source buffer minus emulation
31+
// bytes (the last byte of a 0x00 0x00 0x03 sequence). RBSP is defined in
32+
// section 7.3.1.1 of the H.265 standard, similar to H264.
33+
rtc::ByteBufferWriter rbsp_buffer;
34+
for (size_t i = 0; i < byte_length_;) {
35+
// Be careful about over/underflow here. byte_length_ - 3 can underflow, and
36+
// i + 3 can overflow, but byte_length_ - i can't, because i < byte_length_
37+
// above, and that expression will produce the number of bytes left in
38+
// the stream including the byte at i.
39+
if (byte_length_ - i >= 3 && sps_[i] == 0 && sps_[i + 1] == 0 &&
40+
sps_[i + 2] == 3) {
41+
// Two rbsp bytes + the emulation byte.
42+
rbsp_buffer.WriteBytes(sps_bytes + i, 2);
43+
i += 3;
44+
} else {
45+
// Single rbsp byte.
46+
rbsp_buffer.WriteBytes(sps_bytes + i, 1);
47+
i++;
48+
}
49+
}
50+
51+
// Now, we need to use a bit buffer to parse through the actual HEVC SPS
52+
// format. See Section 7.3.2.1.1 ("Sequence parameter set data syntax") of the
53+
// H.265 standard for a complete description.
54+
// Since we only care about resolution, we ignore the majority of fields, but
55+
// we still have to actively parse through a lot of the data, since many of
56+
// the fields have variable size.
57+
// Unlike H264, for H265, the picture size is indicated by pic_width_in_luma_samples
58+
// and pic_height_in_luma_samples, if conformance_window_flag !=1;
59+
// When conformance_window_flag is 1, the width is adjusted with con_win_xx_offset
60+
//
61+
rtc::BitBuffer parser(reinterpret_cast<const uint8_t*>(rbsp_buffer.Data()),
62+
rbsp_buffer.Length());
63+
64+
// The golomb values we have to read, not just consume.
65+
uint32_t golomb_ignored;
66+
67+
// separate_colour_plane_flag is optional (assumed 0), but has implications
68+
// about the ChromaArrayType, which modifies how we treat crop coordinates.
69+
uint32_t separate_colour_plane_flag = 0;
70+
// chroma_format_idc will be ChromaArrayType if separate_colour_plane_flag is
71+
// 0. It defaults to 1, when not specified.
72+
uint32_t chroma_format_idc = 1;
73+
74+
75+
// sps_video_parameter_set_id: u(4)
76+
RETURN_FALSE_ON_FAIL(parser.ConsumeBits(4));
77+
// sps_max_sub_layers_minus1: u(3)
78+
uint32_t sps_max_sub_layers_minus1 = 0;
79+
RETURN_FALSE_ON_FAIL(parser.ReadBits(&sps_max_sub_layers_minus1, 3));
80+
// sps_temporal_id_nesting_flag: u(1)
81+
RETURN_FALSE_ON_FAIL(parser.ConsumeBits(1));
82+
// profile_tier_level(1, sps_max_sub_layers_minus1). We are acutally not
83+
// using them, so read/skip over it.
84+
// general_profile_space+general_tier_flag+general_prfile_idc: u(8)
85+
RETURN_FALSE_ON_FAIL(parser.ConsumeBytes(1));
86+
// general_profile_compatabilitiy_flag[32]
87+
RETURN_FALSE_ON_FAIL(parser.ConsumeBytes(4));
88+
// general_progressive_source_flag + interlaced_source_flag+ non-packed_constraint
89+
// flag + frame_only_constraint_flag: u(4)
90+
RETURN_FALSE_ON_FAIL(parser.ConsumeBits(4));
91+
// general_profile_idc decided flags or reserved. u(43)
92+
RETURN_FALSE_ON_FAIL(parser.ConsumeBits(43));
93+
// general_inbld_flag or reserved 0: u(1)
94+
RETURN_FALSE_ON_FAIL(parser.ConsumeBits(1));
95+
// general_level_idc: u(8)
96+
RETURN_FALSE_ON_FAIL(parser.ConsumeBytes(1));
97+
// if max_sub_layers_minus1 >=1, read the sublayer profile information
98+
std::vector<uint32_t> sub_layer_profile_present_flags;
99+
std::vector<uint32_t> sub_layer_level_present_flags;
100+
uint32_t sub_layer_profile_present = 0;
101+
uint32_t sub_layer_level_present = 0;
102+
for (uint32_t i = 0; i < sps_max_sub_layers_minus1; i++) {
103+
//sublayer_profile_present_flag and sublayer_level_presnet_flag: u(2)
104+
RETURN_FALSE_ON_FAIL(parser.ReadBits(&sub_layer_profile_present, 1));
105+
RETURN_FALSE_ON_FAIL(parser.ReadBits(&sub_layer_level_present, 1));
106+
sub_layer_profile_present_flags.push_back(sub_layer_profile_present);
107+
sub_layer_level_present_flags.push_back(sub_layer_level_present);
108+
}
109+
if (sps_max_sub_layers_minus1 > 0) {
110+
for (uint32_t j = sps_max_sub_layers_minus1; j < 8; j++) {
111+
// reserved 2 bits: u(2)
112+
RETURN_FALSE_ON_FAIL(parser.ConsumeBits(2));
113+
}
114+
}
115+
for (uint32_t k = 0; k < sps_max_sub_layers_minus1; k++) {
116+
if(sub_layer_profile_present_flags[k]) {//
117+
// sub_layer profile_space/tier_flag/profile_idc. ignored. u(8)
118+
RETURN_FALSE_ON_FAIL(parser.ConsumeBytes(1));
119+
// profile_compatability_flag: u(32)
120+
RETURN_FALSE_ON_FAIL(parser.ConsumeBytes(4));
121+
// sub_layer progressive_source_flag/interlaced_source_flag/
122+
// non_packed_constraint_flag/frame_only_constraint_flag: u(4)
123+
RETURN_FALSE_ON_FAIL(parser.ConsumeBits(4));
124+
// following 43-bits are profile_idc specific. We simply read/skip it. u(43)
125+
RETURN_FALSE_ON_FAIL(parser.ConsumeBits(43));
126+
// 1-bit profile_idc specific inbld flag. We simply read/skip it. u(1)
127+
RETURN_FALSE_ON_FAIL(parser.ConsumeBits(1));
128+
}
129+
if (sub_layer_level_present_flags[k]) {
130+
// sub_layer_level_idc: u(8)
131+
RETURN_FALSE_ON_FAIL(parser.ConsumeBytes(1));
132+
}
133+
}
134+
//sps_seq_parameter_set_id: ue(v)
135+
RETURN_FALSE_ON_FAIL(parser.ReadExponentialGolomb(&golomb_ignored));
136+
// chrome_format_idc: ue(v)
137+
RETURN_FALSE_ON_FAIL(parser.ReadExponentialGolomb(&chroma_format_idc));
138+
if (chroma_format_idc == 3) {
139+
// seperate_colour_plane_flag: u(1)
140+
RETURN_FALSE_ON_FAIL(parser.ReadBits(&separate_colour_plane_flag, 1));
141+
}
142+
uint32_t pic_width_in_luma_samples = 0;
143+
uint32_t pic_height_in_luma_samples = 0;
144+
// pic_width_in_luma_samples: ue(v)
145+
RETURN_FALSE_ON_FAIL(parser.ReadExponentialGolomb(&pic_width_in_luma_samples));
146+
// pic_height_in_luma_samples: ue(v)
147+
RETURN_FALSE_ON_FAIL(parser.ReadExponentialGolomb(&pic_height_in_luma_samples));
148+
// conformance_window_flag: u(1)
149+
uint32_t conformance_window_flag = 0;
150+
RETURN_FALSE_ON_FAIL(parser.ReadBits(&conformance_window_flag, 1));
151+
152+
uint32_t conf_win_left_offset = 0;
153+
uint32_t conf_win_right_offset = 0;
154+
uint32_t conf_win_top_offset = 0;
155+
uint32_t conf_win_bottom_offset = 0;
156+
if (conformance_window_flag) {
157+
// conf_win_left_offset: ue(v)
158+
RETURN_FALSE_ON_FAIL(parser.ReadExponentialGolomb(&conf_win_left_offset));
159+
// conf_win_right_offset: ue(v)
160+
RETURN_FALSE_ON_FAIL(parser.ReadExponentialGolomb(&conf_win_right_offset));
161+
// conf_win_top_offset: ue(v)
162+
RETURN_FALSE_ON_FAIL(parser.ReadExponentialGolomb(&conf_win_top_offset));
163+
// conf_win_bottom_offset: ue(v)
164+
RETURN_FALSE_ON_FAIL(parser.ReadExponentialGolomb(&conf_win_bottom_offset));
165+
}
166+
167+
//For enough to get the resolution information. calcaluate according to HEVC spec 7.4.3.2
168+
int width = 0;
169+
int height = 0;
170+
171+
width = pic_width_in_luma_samples;
172+
height = pic_height_in_luma_samples;
173+
174+
if (conformance_window_flag) {
175+
int sub_width_c = ((1 == chroma_format_idc) || (2 == chroma_format_idc)) &&
176+
(0 == separate_colour_plane_flag) ? 2 : 1;
177+
int sub_height_c = (1 == chroma_format_idc) && (0 == separate_colour_plane_flag) ? 2 : 1;
178+
//the offset includes the pixel within conformance window. so don't need to +1 as per spec
179+
width -= sub_width_c*(conf_win_right_offset + conf_win_left_offset);
180+
height -= sub_height_c*(conf_win_top_offset + conf_win_bottom_offset);
181+
}
182+
183+
width_ = width;
184+
height_ = height;
185+
return true;
186+
187+
}
188+
189+
} // namespace webrtc

0 commit comments

Comments
 (0)