From 1e1dd7760413fd9135520d9c8071ffb542e23ea3 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Thu, 16 Nov 2017 15:44:14 +0100 Subject: [PATCH] Implement equals() and hashCode() for VideoCodecInfo. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To be able to compare VideoCodecInfos in a nice way in Java and still use the correct criteria for comparing H264 codec infos. A similar thing was done for Obj-C here: https://webrtc-review.googlesource.com/c/src/+/4383 Bug: webrtc:7925 Change-Id: I43f532d4efa557fc8fe25a82eebc35072b91e6db Reviewed-on: https://webrtc-review.googlesource.com/23240 Reviewed-by: Sami Kalliomäki Commit-Queue: Anders Carlsson Cr-Commit-Position: refs/heads/master@{#20716} --- sdk/android/BUILD.gn | 2 +- .../webrtc/DefaultVideoEncoderFactory.java | 32 ++++--------------- .../webrtc/HardwareVideoEncoderFactory.java | 13 ++++++++ .../api/org/webrtc/VideoCodecInfo.java | 21 ++++++++++++ ...tory.cc => hardwarevideoencoderfactory.cc} | 21 +++--------- 5 files changed, 47 insertions(+), 42 deletions(-) rename sdk/android/src/jni/{defaultvideoencoderfactory.cc => hardwarevideoencoderfactory.cc} (67%) diff --git a/sdk/android/BUILD.gn b/sdk/android/BUILD.gn index f9e47ac9c4..e78fa4d524 100644 --- a/sdk/android/BUILD.gn +++ b/sdk/android/BUILD.gn @@ -126,7 +126,7 @@ rtc_static_library("video_jni") { "src/jni/androidvideotracksource.cc", "src/jni/androidvideotracksource.h", "src/jni/androidvideotracksource_jni.cc", - "src/jni/defaultvideoencoderfactory.cc", + "src/jni/hardwarevideoencoderfactory.cc", "src/jni/jni_generator_helper.h", "src/jni/nv12buffer_jni.cc", "src/jni/nv21buffer_jni.cc", diff --git a/sdk/android/api/org/webrtc/DefaultVideoEncoderFactory.java b/sdk/android/api/org/webrtc/DefaultVideoEncoderFactory.java index db6af87e7b..309ae7432b 100644 --- a/sdk/android/api/org/webrtc/DefaultVideoEncoderFactory.java +++ b/sdk/android/api/org/webrtc/DefaultVideoEncoderFactory.java @@ -10,8 +10,8 @@ package org.webrtc; -import java.util.ArrayList; import java.util.Arrays; +import java.util.LinkedHashSet; import java.util.List; public class DefaultVideoEncoderFactory implements VideoEncoderFactory { @@ -33,38 +33,20 @@ public class DefaultVideoEncoderFactory implements VideoEncoderFactory { @Override public VideoEncoder createEncoder(VideoCodecInfo info) { - List hardwareSupportedCodecs = - Arrays.asList(hardwareVideoEncoderFactory.getSupportedCodecs()); - if (containsSameCodec(hardwareSupportedCodecs, info)) { - return hardwareVideoEncoderFactory.createEncoder(info); - } else { - return softwareVideoEncoderFactory.createEncoder(info); + final VideoEncoder videoEncoder = hardwareVideoEncoderFactory.createEncoder(info); + if (videoEncoder != null) { + return videoEncoder; } + return softwareVideoEncoderFactory.createEncoder(info); } @Override public VideoCodecInfo[] getSupportedCodecs() { - List supportedCodecInfos = new ArrayList<>(); + LinkedHashSet supportedCodecInfos = new LinkedHashSet(); supportedCodecInfos.addAll(Arrays.asList(softwareVideoEncoderFactory.getSupportedCodecs())); - - for (VideoCodecInfo info : hardwareVideoEncoderFactory.getSupportedCodecs()) { - if (!containsSameCodec(supportedCodecInfos, info)) { - supportedCodecInfos.add(info); - } - } + supportedCodecInfos.addAll(Arrays.asList(hardwareVideoEncoderFactory.getSupportedCodecs())); return supportedCodecInfos.toArray(new VideoCodecInfo[supportedCodecInfos.size()]); } - - private static boolean containsSameCodec(List infos, VideoCodecInfo info) { - for (VideoCodecInfo otherInfo : infos) { - if (isSameCodec(info, otherInfo)) { - return true; - } - } - return false; - } - - private static native boolean isSameCodec(VideoCodecInfo info1, VideoCodecInfo info2); } diff --git a/sdk/android/api/org/webrtc/HardwareVideoEncoderFactory.java b/sdk/android/api/org/webrtc/HardwareVideoEncoderFactory.java index 02a96f8969..25b7c77e73 100644 --- a/sdk/android/api/org/webrtc/HardwareVideoEncoderFactory.java +++ b/sdk/android/api/org/webrtc/HardwareVideoEncoderFactory.java @@ -93,6 +93,16 @@ public class HardwareVideoEncoderFactory implements VideoEncoderFactory { Integer yuvColorFormat = MediaCodecUtils.selectColorFormat( MediaCodecUtils.ENCODER_COLOR_FORMATS, info.getCapabilitiesForType(mime)); + if (type == VideoCodecType.H264) { + boolean isHighProfile = isSameH264Profile(input.params, getCodecProperties(type, true)) + && isH264HighProfileSupported(info); + boolean isBaselineProfile = isSameH264Profile(input.params, getCodecProperties(type, false)); + + if (!isHighProfile && !isBaselineProfile) { + return null; + } + } + return new HardwareVideoEncoder(codecName, type, surfaceColorFormat, yuvColorFormat, input.params, getKeyFrameIntervalSec(type), getForcedKeyFrameIntervalMs(type, codecName), createBitrateAdjuster(type, codecName), sharedContext); @@ -269,4 +279,7 @@ public class HardwareVideoEncoderFactory implements VideoEncoderFactory { throw new IllegalArgumentException("Unsupported codec: " + type); } } + + private static native boolean isSameH264Profile( + Map params1, Map params2); } diff --git a/sdk/android/api/org/webrtc/VideoCodecInfo.java b/sdk/android/api/org/webrtc/VideoCodecInfo.java index 208a99203b..9f52cf25d0 100644 --- a/sdk/android/api/org/webrtc/VideoCodecInfo.java +++ b/sdk/android/api/org/webrtc/VideoCodecInfo.java @@ -10,6 +10,8 @@ package org.webrtc; +import java.util.Arrays; +import java.util.Locale; import java.util.Map; /** @@ -45,4 +47,23 @@ public class VideoCodecInfo { this.name = name; this.params = params; } + + @Override + public boolean equals(Object obj) { + if (obj == null) + return false; + if (obj == this) + return true; + if (!(obj instanceof VideoCodecInfo)) + return false; + + VideoCodecInfo otherInfo = (VideoCodecInfo) obj; + return name.equalsIgnoreCase(otherInfo.name) && params.equals(otherInfo.params); + } + + @Override + public int hashCode() { + Object[] values = {name.toUpperCase(Locale.ROOT), params}; + return Arrays.hashCode(values); + } } diff --git a/sdk/android/src/jni/defaultvideoencoderfactory.cc b/sdk/android/src/jni/hardwarevideoencoderfactory.cc similarity index 67% rename from sdk/android/src/jni/defaultvideoencoderfactory.cc rename to sdk/android/src/jni/hardwarevideoencoderfactory.cc index eb04c4fa56..c58b4b2737 100644 --- a/sdk/android/src/jni/defaultvideoencoderfactory.cc +++ b/sdk/android/src/jni/hardwarevideoencoderfactory.cc @@ -14,7 +14,6 @@ #include "media/base/h264_profile_level_id.h" #include "media/base/mediaconstants.h" #include "sdk/android/src/jni/jni_helpers.h" -#include "sdk/android/src/jni/videocodecinfo.h" namespace webrtc { namespace jni { @@ -31,23 +30,13 @@ static bool IsSameH264Profile(const cricket::CodecParameterMap& params1, } JNI_FUNCTION_DECLARATION(jboolean, - DefaultVideoEncoderFactory_isSameCodec, + HardwareVideoEncoderFactory_isSameH264Profile, JNIEnv* jni, jclass, - jobject info1, - jobject info2) { - cricket::VideoCodec codec1 = - cricket::VideoCodec(VideoCodecInfoToSdpVideoFormat(jni, info1)); - cricket::VideoCodec codec2 = - cricket::VideoCodec(VideoCodecInfoToSdpVideoFormat(jni, info2)); - - if (!cricket::CodecNamesEq(codec1.name, codec2.name)) - return false; - if (cricket::CodecNamesEq(codec1.name.c_str(), cricket::kH264CodecName) && - !IsSameH264Profile(codec1.params, codec2.params)) { - return false; - } - return true; + jobject params1, + jobject params2) { + return IsSameH264Profile(JavaToStdMapStrings(jni, params1), + JavaToStdMapStrings(jni, params2)); } } // namespace jni