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

Commit

Permalink
Rebase all changes for HEVC to M70
Browse files Browse the repository at this point in the history
  • Loading branch information
taste1981 committed Oct 22, 2018
1 parent 8d90dd1 commit 49830ab
Show file tree
Hide file tree
Showing 40 changed files with 2,370 additions and 19 deletions.
34 changes: 34 additions & 0 deletions api/video_codecs/video_codec.cc
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,17 @@ bool VideoCodecH264::operator==(const VideoCodecH264& other) const {
(ppsLen == 0 || memcmp(ppsData, other.ppsData, ppsLen) == 0));
}

#ifndef DISABLE_H265
bool VideoCodecH265::operator==(const VideoCodecH265& other) const {
return (frameDroppingOn == other.frameDroppingOn &&
keyFrameInterval == other.keyFrameInterval &&
vpsLen == other.vpsLen && spsLen == other.spsLen &&
ppsLen == other.ppsLen &&
(spsLen == 0 || memcmp(spsData, other.spsData, spsLen) == 0) &&
(ppsLen == 0 || memcmp(ppsData, other.ppsData, ppsLen) == 0));
}
#endif

bool SpatialLayer::operator==(const SpatialLayer& other) const {
return (width == other.width && height == other.height &&
numberOfTemporalLayers == other.numberOfTemporalLayers &&
Expand Down Expand Up @@ -111,9 +122,24 @@ const VideoCodecH264& VideoCodec::H264() const {
return codec_specific_.H264;
}

#ifndef DISABLE_H265
VideoCodecH265* VideoCodec::H265() {
RTC_DCHECK_EQ(codecType, kVideoCodecH265);
return &codec_specific_.H265;
}

const VideoCodecH265& VideoCodec::H265() const {
RTC_DCHECK_EQ(codecType, kVideoCodecH265);
return codec_specific_.H265;
}
#endif

static const char* kPayloadNameVp8 = "VP8";
static const char* kPayloadNameVp9 = "VP9";
static const char* kPayloadNameH264 = "H264";
#ifndef DISABLE_H265
static const char* kPayloadNameH265 = "H265";
#endif
static const char* kPayloadNameI420 = "I420";
static const char* kPayloadNameGeneric = "Generic";
static const char* kPayloadNameMultiplex = "Multiplex";
Expand All @@ -130,6 +156,10 @@ const char* CodecTypeToPayloadString(VideoCodecType type) {
return kPayloadNameVp9;
case kVideoCodecH264:
return kPayloadNameH264;
#ifndef DISABLE_H265
case kVideoCodecH265:
return kPayloadNameH265;
#endif
case kVideoCodecI420:
return kPayloadNameI420;
// Other codecs default to generic.
Expand All @@ -145,6 +175,10 @@ VideoCodecType PayloadStringToCodecType(const std::string& name) {
return kVideoCodecVP9;
if (CodecNamesEq(name.c_str(), kPayloadNameH264))
return kVideoCodecH264;
#ifndef DISABLE_H265
if (CodecNamesEq(name.c_str(), kPayloadNameH265))
return kVideoCodecH265;
#endif
if (CodecNamesEq(name.c_str(), kPayloadNameI420))
return kVideoCodecI420;
if (CodecNamesEq(name.c_str(), kPayloadNameMultiplex))
Expand Down
24 changes: 24 additions & 0 deletions api/video_codecs/video_codec.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,23 @@ struct VideoCodecH264 {
H264::Profile profile;
};

#ifndef DISABLE_H265
struct VideoCodecH265 {
bool operator==(const VideoCodecH265& other) const;
bool operator!=(const VideoCodecH265& other) const {
return !(*this == other);
}
bool frameDroppingOn;
int keyFrameInterval;
const uint8_t* vpsData;
size_t vpsLen;
const uint8_t* spsData;
size_t spsLen;
const uint8_t* ppsData;
size_t ppsLen;
};
#endif

// Translates from name of codec to codec type and vice versa.
const char* CodecTypeToPayloadString(VideoCodecType type);
VideoCodecType PayloadStringToCodecType(const std::string& name);
Expand All @@ -93,6 +110,9 @@ union VideoCodecUnion {
VideoCodecVP8 VP8;
VideoCodecVP9 VP9;
VideoCodecH264 H264;
#ifndef DISABLE_H265
VideoCodecH265 H265;
#endif
};

enum class VideoCodecMode { kRealtimeVideo, kScreensharing };
Expand Down Expand Up @@ -155,6 +175,10 @@ class VideoCodec {
const VideoCodecVP9& VP9() const;
VideoCodecH264* H264();
const VideoCodecH264& H264() const;
#ifndef DISABLE_H265
VideoCodecH265* H265();
const VideoCodecH265& H265() const;
#endif

private:
// TODO(hta): Consider replacing the union with a pointer type.
Expand Down
17 changes: 17 additions & 0 deletions api/video_codecs/video_encoder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,23 @@ VideoCodecH264 VideoEncoder::GetDefaultH264Settings() {
return h264_settings;
}

#ifndef DISABLE_H265
VideoCodecH265 VideoEncoder::GetDefaultH265Settings() {
VideoCodecH265 h265_settings;
memset(&h265_settings, 0, sizeof(h265_settings));

// h265_settings.profile = kProfileBase;
h265_settings.frameDroppingOn = true;
h265_settings.keyFrameInterval = 3000;
h265_settings.spsData = nullptr;
h265_settings.spsLen = 0;
h265_settings.ppsData = nullptr;
h265_settings.ppsLen = 0;

return h265_settings;
}
#endif

VideoEncoder::ScalingSettings::ScalingSettings() = default;

VideoEncoder::ScalingSettings::ScalingSettings(KOff) : ScalingSettings() {}
Expand Down
4 changes: 3 additions & 1 deletion api/video_codecs/video_encoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,9 @@ class VideoEncoder {
static VideoCodecVP8 GetDefaultVp8Settings();
static VideoCodecVP9 GetDefaultVp9Settings();
static VideoCodecH264 GetDefaultH264Settings();

#ifndef DISABLE_H265
static VideoCodecH265 GetDefaultH265Settings();
#endif
virtual ~VideoEncoder() {}

// Initialize the encoder with the information from the codecSettings
Expand Down
4 changes: 2 additions & 2 deletions call/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ if (rtc_include_tests) {
]
deps = [
":bitrate_allocator",
"//test:test_support",
"../test:test_support",
]
}
rtc_source_set("mock_call_interfaces") {
Expand All @@ -446,7 +446,7 @@ if (rtc_include_tests) {
]
deps = [
":call_interfaces",
"//test:test_support",
"../test:test_support",
]
}

Expand Down
3 changes: 3 additions & 0 deletions common_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,9 @@ enum VideoCodecType {
kVideoCodecVP8,
kVideoCodecVP9,
kVideoCodecH264,
#ifndef DISABLE_H265
kVideoCodecH265,
#endif
kVideoCodecI420,
kVideoCodecMultiplex,
// DEPRECATED. Do not use.
Expand Down
13 changes: 13 additions & 0 deletions common_video/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,19 @@ rtc_static_library("common_video") {
"video_render_frames.h",
]

if (rtc_use_h265) {
sources += [
"h265/h265_common.cc",
"h265/h265_common.h",
"h265/h265_pps_parser.cc",
"h265/h265_pps_parser.h",
"h265/h265_sps_parser.cc",
"h265/h265_sps_parser.h",
"h265/h265_vps_parser.cc",
"h265/h265_vps_parser.h",
]
}

deps = [
"..:webrtc_common",
"../api/video:video_bitrate_allocation",
Expand Down
110 changes: 110 additions & 0 deletions common_video/h265/h265_common.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/

#include "common_video/h265/h265_common.h"

namespace webrtc {
namespace H265 {

const uint8_t kNaluTypeMask = 0x7E;

std::vector<NaluIndex> FindNaluIndices(const uint8_t* buffer,
size_t buffer_size) {
// This is sorta like Boyer-Moore, but with only the first optimization step:
// given a 3-byte sequence we're looking at, if the 3rd byte isn't 1 or 0,
// skip ahead to the next 3-byte sequence. 0s and 1s are relatively rare, so
// this will skip the majority of reads/checks.
std::vector<NaluIndex> sequences;
if (buffer_size < kNaluShortStartSequenceSize)
return sequences;

const size_t end = buffer_size - kNaluShortStartSequenceSize;
for (size_t i = 0; i < end;) {
if (buffer[i + 2] > 1) {
i += 3;
} else if (buffer[i + 2] == 1 && buffer[i + 1] == 0 && buffer[i] == 0) {
// We found a start sequence, now check if it was a 3 of 4 byte one.
NaluIndex index = {i, i + 3, 0};
if (index.start_offset > 0 && buffer[index.start_offset - 1] == 0)
--index.start_offset;

// Update length of previous entry.
auto it = sequences.rbegin();
if (it != sequences.rend())
it->payload_size = index.start_offset - it->payload_start_offset;

sequences.push_back(index);

i += 3;
} else {
++i;
}
}

// Update length of last entry, if any.
auto it = sequences.rbegin();
if (it != sequences.rend())
it->payload_size = buffer_size - it->payload_start_offset;

return sequences;
}

NaluType ParseNaluType(uint8_t data) {
return static_cast<NaluType>((data & kNaluTypeMask) >> 1);
}

std::vector<uint8_t> ParseRbsp(const uint8_t* data, size_t length) {
std::vector<uint8_t> out;
out.reserve(length);

for (size_t i = 0; i < length;) {
// Be careful about over/underflow here. byte_length_ - 3 can underflow, and
// i + 3 can overflow, but byte_length_ - i can't, because i < byte_length_
// above, and that expression will produce the number of bytes left in
// the stream including the byte at i.
if (length - i >= 3 && !data[i] && !data[i + 1] && data[i + 2] == 3) {
// Two rbsp bytes.
out.push_back(data[i++]);
out.push_back(data[i++]);
// Skip the emulation byte.
i++;
} else {
// Single rbsp byte.
out.push_back(data[i++]);
}
}
return out;
}

void WriteRbsp(const uint8_t* bytes, size_t length, rtc::Buffer* destination) {
static const uint8_t kZerosInStartSequence = 2;
static const uint8_t kEmulationByte = 0x03u;
size_t num_consecutive_zeros = 0;
destination->EnsureCapacity(destination->size() + length);

for (size_t i = 0; i < length; ++i) {
uint8_t byte = bytes[i];
if (byte <= kEmulationByte &&
num_consecutive_zeros >= kZerosInStartSequence) {
// Need to escape.
destination->AppendData(kEmulationByte);
num_consecutive_zeros = 0;
}
destination->AppendData(byte);
if (byte == 0) {
++num_consecutive_zeros;
} else {
num_consecutive_zeros = 0;
}
}
}

} // namespace H265
} // namespace webrtc
Loading

0 comments on commit 49830ab

Please sign in to comment.