summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorstefan@webrtc.org <stefan@webrtc.org@4adac7df-926f-26a2-2b94-8c16560cd09d>2014-07-04 12:42:07 +0000
committerstefan@webrtc.org <stefan@webrtc.org@4adac7df-926f-26a2-2b94-8c16560cd09d>2014-07-04 12:42:07 +0000
commit2d4a80c05adffe07b48dc235475852450cd90568 (patch)
tree8be3d90f488a107bac7e54dbecc02ffea78c231e
parent65afbf3e1da598f94f47eb0c11fe2b668e4f30f4 (diff)
downloadwebrtc-2d4a80c05adffe07b48dc235475852450cd90568.tar.gz
Add boilerplate code for H.264.
R=mflodman@webrtc.org, niklas.enbom@webrtc.org Review URL: https://webrtc-codereview.appspot.com/17849005 git-svn-id: http://webrtc.googlecode.com/svn/trunk/webrtc@6603 4adac7df-926f-26a2-2b94-8c16560cd09d
-rw-r--r--common_types.h15
-rw-r--r--engine_configurations.h1
-rw-r--r--modules/interface/module_common_types.h10
-rw-r--r--modules/rtp_rtcp/source/rtp_payload_registry.cc2
-rw-r--r--modules/rtp_rtcp/source/rtp_receiver_video.cc2
-rw-r--r--modules/rtp_rtcp/source/rtp_sender_video.cc2
-rw-r--r--modules/video_coding/main/interface/video_coding_defines.h1
-rw-r--r--modules/video_coding/main/source/codec_database.cc34
-rw-r--r--modules/video_coding/main/source/internal_defines.h9
-rw-r--r--test/encoder_settings.cc16
-rw-r--r--video/loopback.cc15
-rw-r--r--video_engine/test/auto_test/source/vie_autotest.cc3
-rw-r--r--video_engine/vie_codec_impl.cc16
13 files changed, 114 insertions, 12 deletions
diff --git a/common_types.h b/common_types.h
index 6892a83f..193e2818 100644
--- a/common_types.h
+++ b/common_types.h
@@ -587,10 +587,24 @@ struct VideoCodecVP8 {
}
};
+// H264 specific.
+struct VideoCodecH264
+{
+ VideoCodecProfile profile;
+ bool frameDroppingOn;
+ int keyFrameInterval;
+ // These are NULL/0 if not externally negotiated.
+ const uint8_t* spsData;
+ size_t spsLen;
+ const uint8_t* ppsData;
+ size_t ppsLen;
+};
+
// Video codec types
enum VideoCodecType
{
kVideoCodecVP8,
+ kVideoCodecH264,
kVideoCodecI420,
kVideoCodecRED,
kVideoCodecULPFEC,
@@ -601,6 +615,7 @@ enum VideoCodecType
union VideoCodecUnion
{
VideoCodecVP8 VP8;
+ VideoCodecH264 H264;
};
diff --git a/engine_configurations.h b/engine_configurations.h
index be858b8e..e9f23097 100644
--- a/engine_configurations.h
+++ b/engine_configurations.h
@@ -51,6 +51,7 @@
#define VIDEOCODEC_I420
#define VIDEOCODEC_VP8
+#define VIDEOCODEC_H264
// ============================================================================
// VoiceEngine
diff --git a/modules/interface/module_common_types.h b/modules/interface/module_common_types.h
index 2c947071..e37313c9 100644
--- a/modules/interface/module_common_types.h
+++ b/modules/interface/module_common_types.h
@@ -75,14 +75,22 @@ struct RTPVideoHeaderVP8 {
bool beginningOfPartition; // True if this packet is the first
// in a VP8 partition. Otherwise false
};
+
+struct RTPVideoHeaderH264 {
+ uint8_t nalu_header;
+ bool single_nalu;
+};
+
union RTPVideoTypeHeader {
RTPVideoHeaderVP8 VP8;
+ RTPVideoHeaderH264 H264;
};
enum RtpVideoCodecTypes {
kRtpVideoNone,
kRtpVideoGeneric,
- kRtpVideoVp8
+ kRtpVideoVp8,
+ kRtpVideoH264
};
struct RTPVideoHeader {
uint16_t width; // size
diff --git a/modules/rtp_rtcp/source/rtp_payload_registry.cc b/modules/rtp_rtcp/source/rtp_payload_registry.cc
index db2e4cd3..26db8f32 100644
--- a/modules/rtp_rtcp/source/rtp_payload_registry.cc
+++ b/modules/rtp_rtcp/source/rtp_payload_registry.cc
@@ -434,6 +434,8 @@ class RTPPayloadVideoStrategy : public RTPPayloadStrategy {
RtpVideoCodecTypes videoType = kRtpVideoGeneric;
if (ModuleRTPUtility::StringCompare(payloadName, "VP8", 3)) {
videoType = kRtpVideoVp8;
+ } else if (ModuleRTPUtility::StringCompare(payloadName, "H264", 4)) {
+ videoType = kRtpVideoH264;
} else if (ModuleRTPUtility::StringCompare(payloadName, "I420", 4)) {
videoType = kRtpVideoGeneric;
} else if (ModuleRTPUtility::StringCompare(payloadName, "ULPFEC", 6)) {
diff --git a/modules/rtp_rtcp/source/rtp_receiver_video.cc b/modules/rtp_rtcp/source/rtp_receiver_video.cc
index 5bb519f6..26159916 100644
--- a/modules/rtp_rtcp/source/rtp_receiver_video.cc
+++ b/modules/rtp_rtcp/source/rtp_receiver_video.cc
@@ -113,6 +113,8 @@ int32_t RTPReceiverVideo::ParseVideoCodecSpecific(
return ReceiveGenericCodec(rtp_header, payload_data, payload_data_length);
case kRtpVideoVp8:
return ReceiveVp8Codec(rtp_header, payload_data, payload_data_length);
+ case kRtpVideoH264:
+ assert(false); // Not yet supported.
case kRtpVideoNone:
break;
}
diff --git a/modules/rtp_rtcp/source/rtp_sender_video.cc b/modules/rtp_rtcp/source/rtp_sender_video.cc
index 5d8ae166..e4138ff5 100644
--- a/modules/rtp_rtcp/source/rtp_sender_video.cc
+++ b/modules/rtp_rtcp/source/rtp_sender_video.cc
@@ -90,6 +90,8 @@ int32_t RTPSenderVideo::RegisterVideoPayload(
RtpVideoCodecTypes videoType = kRtpVideoGeneric;
if (ModuleRTPUtility::StringCompare(payloadName, "VP8",3)) {
videoType = kRtpVideoVp8;
+ } else if (ModuleRTPUtility::StringCompare(payloadName, "H264", 4)) {
+ videoType = kRtpVideoH264;
} else if (ModuleRTPUtility::StringCompare(payloadName, "I420", 4)) {
videoType = kRtpVideoGeneric;
} else {
diff --git a/modules/video_coding/main/interface/video_coding_defines.h b/modules/video_coding/main/interface/video_coding_defines.h
index fab91afd..c5f93cb1 100644
--- a/modules/video_coding/main/interface/video_coding_defines.h
+++ b/modules/video_coding/main/interface/video_coding_defines.h
@@ -40,6 +40,7 @@ namespace webrtc {
#define VCM_ULPFEC_PAYLOAD_TYPE 97
#define VCM_VP8_PAYLOAD_TYPE 100
#define VCM_I420_PAYLOAD_TYPE 124
+#define VCM_H264_PAYLOAD_TYPE 127
enum VCMVideoProtection {
kProtectionNack, // Both send-side and receive-side
diff --git a/modules/video_coding/main/source/codec_database.cc b/modules/video_coding/main/source/codec_database.cc
index e7a9d91b..7e26bea4 100644
--- a/modules/video_coding/main/source/codec_database.cc
+++ b/modules/video_coding/main/source/codec_database.cc
@@ -102,6 +102,30 @@ bool VCMCodecDataBase::Codec(int list_id,
return true;
}
#endif
+#ifdef VIDEOCODEC_H264
+ case VCM_H264_IDX: {
+ strncpy(settings->plName, "H264", 5);
+ settings->codecType = kVideoCodecH264;
+ // 96 to 127 dynamic payload types for video codecs.
+ settings->plType = VCM_H264_PAYLOAD_TYPE;
+ settings->startBitrate = 100;
+ settings->minBitrate = VCM_MIN_BITRATE;
+ settings->maxBitrate = 0;
+ settings->maxFramerate = VCM_DEFAULT_FRAME_RATE;
+ settings->width = VCM_DEFAULT_CODEC_WIDTH;
+ settings->height = VCM_DEFAULT_CODEC_HEIGHT;
+ settings->numberOfSimulcastStreams = 0;
+ settings->qpMax = 56;
+ settings->codecSpecific.H264.profile = kProfileBase;
+ settings->codecSpecific.H264.frameDroppingOn = true;
+ settings->codecSpecific.H264.keyFrameInterval = 3000;
+ settings->codecSpecific.H264.spsData = NULL;
+ settings->codecSpecific.H264.spsLen = 0;
+ settings->codecSpecific.H264.ppsData = NULL;
+ settings->codecSpecific.H264.ppsLen = 0;
+ return true;
+ }
+#endif
#ifdef VIDEOCODEC_I420
case VCM_I420_IDX: {
strncpy(settings->plName, "I420", 5);
@@ -316,8 +340,7 @@ bool VCMCodecDataBase::RequiresEncoderReset(const VideoCodec& new_send_codec) {
case kVideoCodecVP8:
if (memcmp(&new_send_codec.codecSpecific.VP8,
&send_codec_.codecSpecific.VP8,
- sizeof(new_send_codec.codecSpecific.VP8)) !=
- 0) {
+ sizeof(new_send_codec.codecSpecific.VP8)) != 0) {
return true;
}
break;
@@ -327,6 +350,12 @@ bool VCMCodecDataBase::RequiresEncoderReset(const VideoCodec& new_send_codec) {
case kVideoCodecI420:
case kVideoCodecRED:
case kVideoCodecULPFEC:
+ case kVideoCodecH264:
+ if (memcmp(&new_send_codec.codecSpecific.H264,
+ &send_codec_.codecSpecific.H264,
+ sizeof(new_send_codec.codecSpecific.H264)) != 0) {
+ return true;
+ }
break;
// Unknown codec type, reset just to be sure.
case kVideoCodecUnknown:
@@ -619,6 +648,7 @@ VCMGenericDecoder* VCMCodecDataBase::CreateDecoder(VideoCodecType type) const {
return new VCMGenericDecoder(*(new I420Decoder));
#endif
default:
+ LOG(LS_WARNING) << "No internal decoder of this type exists.";
return NULL;
}
}
diff --git a/modules/video_coding/main/source/internal_defines.h b/modules/video_coding/main/source/internal_defines.h
index efc6d8dd..1128312b 100644
--- a/modules/video_coding/main/source/internal_defines.h
+++ b/modules/video_coding/main/source/internal_defines.h
@@ -39,10 +39,15 @@ inline uint32_t MaskWord64ToUWord32(int64_t w64)
#else
#define VCM_VP8_IDX VCM_NO_CODEC_IDX
#endif
+#ifdef VIDEOCODEC_H264
+ #define VCM_H264_IDX VCM_VP8_IDX + 1
+#else
+ #define VCM_H264_IDX VCM_VP8_IDX
+#endif
#ifdef VIDEOCODEC_I420
- #define VCM_I420_IDX VCM_VP8_IDX + 1
+ #define VCM_I420_IDX VCM_H264_IDX + 1
#else
- #define VCM_I420_IDX VCM_VP8_IDX
+ #define VCM_I420_IDX VCM_H264_IDX
#endif
#define VCM_NUM_VIDEO_CODECS_AVAILABLE VCM_I420_IDX + 1
diff --git a/test/encoder_settings.cc b/test/encoder_settings.cc
index 5193be65..9842d1ed 100644
--- a/test/encoder_settings.cc
+++ b/test/encoder_settings.cc
@@ -59,9 +59,13 @@ VideoCodec CreateDecoderVideoCodec(
codec.plType = encoder_settings.payload_type;
strcpy(codec.plName, encoder_settings.payload_name.c_str());
- codec.codecType =
- (encoder_settings.payload_name == "VP8" ? kVideoCodecVP8
- : kVideoCodecGeneric);
+ if (encoder_settings.payload_name == "VP8") {
+ codec.codecType = kVideoCodecVP8;
+ } else if (encoder_settings.payload_name == "H264") {
+ codec.codecType = kVideoCodecH264;
+ } else {
+ codec.codecType = kVideoCodecGeneric;
+ }
if (codec.codecType == kVideoCodecVP8) {
codec.codecSpecific.VP8.resilience = kResilientStream;
@@ -73,6 +77,12 @@ VideoCodec CreateDecoderVideoCodec(
codec.codecSpecific.VP8.keyFrameInterval = 3000;
}
+ if (codec.codecType == kVideoCodecH264) {
+ codec.codecSpecific.H264.profile = kProfileBase;
+ codec.codecSpecific.H264.frameDroppingOn = true;
+ codec.codecSpecific.H264.keyFrameInterval = 3000;
+ }
+
codec.width = 320;
codec.height = 180;
codec.startBitrate = codec.minBitrate = codec.maxBitrate = 300;
diff --git a/video/loopback.cc b/video/loopback.cc
index ea65ebb4..276f1d45 100644
--- a/video/loopback.cc
+++ b/video/loopback.cc
@@ -48,6 +48,9 @@ size_t StartBitrate() { return static_cast<size_t>(FLAGS_start_bitrate); }
DEFINE_int32(max_bitrate, 800, "Maximum video bitrate.");
size_t MaxBitrate() { return static_cast<size_t>(FLAGS_max_bitrate); }
+
+DEFINE_string(codec, "VP8", "Video codec to use.");
+std::string Codec() { return static_cast<std::string>(FLAGS_codec); }
} // namespace flags
static const uint32_t kSendSsrc = 0x654321;
@@ -72,10 +75,16 @@ void Loopback() {
send_config.rtp.ssrcs.push_back(kSendSsrc);
send_config.local_renderer = local_preview.get();
-
- scoped_ptr<VP8Encoder> encoder(VP8Encoder::Create());
+ scoped_ptr<VideoEncoder> encoder;
+ if (flags::Codec() == "VP8") {
+ encoder.reset(VP8Encoder::Create());
+ } else {
+ // Codec not supported.
+ assert(false && "Codec not supported!");
+ return;
+ }
send_config.encoder_settings.encoder = encoder.get();
- send_config.encoder_settings.payload_name = "VP8";
+ send_config.encoder_settings.payload_name = flags::Codec();
send_config.encoder_settings.payload_type = 124;
std::vector<VideoStream> video_streams = test::CreateVideoStreams(1);
VideoStream* stream = &video_streams[0];
diff --git a/video_engine/test/auto_test/source/vie_autotest.cc b/video_engine/test/auto_test/source/vie_autotest.cc
index 188567cb..fb1a46f2 100644
--- a/video_engine/test/auto_test/source/vie_autotest.cc
+++ b/video_engine/test/auto_test/source/vie_autotest.cc
@@ -101,6 +101,9 @@ void ViEAutoTest::PrintVideoCodec(const webrtc::VideoCodec videoCodec)
case webrtc::kVideoCodecI420:
ViETest::Log("\tcodecType: I420");
break;
+ case webrtc::kVideoCodecH264:
+ ViETest::Log("\tcodecType: H264");
+ break;
case webrtc::kVideoCodecRED:
ViETest::Log("\tcodecType: RED");
break;
diff --git a/video_engine/vie_codec_impl.cc b/video_engine/vie_codec_impl.cc
index 3ba56de5..050958e2 100644
--- a/video_engine/vie_codec_impl.cc
+++ b/video_engine/vie_codec_impl.cc
@@ -69,6 +69,18 @@ static void LogCodec(const VideoCodec& codec) {
<< ", qp max "
<< codec.simulcastStream[idx].qpMax;
}
+ } else if (codec.codecType == kVideoCodecH264) {
+ LOG(LS_INFO) << "H264 specific settings";
+ LOG(LS_INFO) << "profile: "
+ << codec.codecSpecific.H264.profile
+ << ", framedropping: "
+ << codec.codecSpecific.H264.frameDroppingOn
+ << ", keyFrameInterval: "
+ << codec.codecSpecific.H264.keyFrameInterval
+ << ", spslen: "
+ << codec.codecSpecific.H264.spsLen
+ << ", ppslen: "
+ << codec.codecSpecific.H264.ppsLen;
}
}
@@ -629,7 +641,9 @@ bool ViECodecImpl::CodecValid(const VideoCodec& video_codec) {
} else if ((video_codec.codecType == kVideoCodecVP8 &&
strncmp(video_codec.plName, "VP8", 4) == 0) ||
(video_codec.codecType == kVideoCodecI420 &&
- strncmp(video_codec.plName, "I420", 4) == 0)) {
+ strncmp(video_codec.plName, "I420", 4) == 0) ||
+ (video_codec.codecType == kVideoCodecH264 &&
+ strncmp(video_codec.plName, "H264", 4) == 0)) {
// OK.
} else if (video_codec.codecType != kVideoCodecGeneric) {
LOG(LS_ERROR) << "Codec type and name mismatch.";