文章

WebRTC安卓视频解码器创建过程分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
bool VideoDecoderSoftwareFallbackWrapper::Configure(const Settings& settings) {
  decoder_settings_ = settings;

  if (webrtc::field_trial::IsEnabled("WebRTC-Video-ForcedSwDecoderFallback")) {
    RTC_LOG(LS_INFO) << "Forced software decoder fallback enabled.";
    RTC_DCHECK(decoder_type_ == DecoderType::kNone);
    return InitFallbackDecoder();
  }
  if (InitHwDecoder()) {
    RTC_LOG(LS_ERROR) << "gezhaoyou hhhhhhhh ffffff.";
    return true;
  }
  RTC_LOG(LS_ERROR) << "gezhaoyou hhhhhhhh nnnnnnnnnnn.";
  RTC_DCHECK(decoder_type_ == DecoderType::kNone);
  return InitFallbackDecoder();
}

创建硬解

1
2
3
4
5
6
7
8
9
bool VideoDecoderWrapper::Configure(const Settings& settings) {
  RTC_DCHECK_RUN_ON(&decoder_thread_checker_);
  JNIEnv* jni = AttachCurrentThreadIfNeeded();
  decoder_settings_ = settings;
  RTC_LOG(LS_ERROR) << "gezhaoyou InitFallbackDecoder nnnnnnnn.";
  return ConfigureInternal(jni);
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
static jlong JNI_VideoDecoderFallback_CreateDecoder(
    JNIEnv* jni,
    const JavaParamRef<jobject>& j_fallback_decoder,
    const JavaParamRef<jobject>& j_primary_decoder) {
  std::unique_ptr<VideoDecoder> fallback_decoder =
      JavaToNativeVideoDecoder(jni, j_fallback_decoder);
  std::unique_ptr<VideoDecoder> primary_decoder =
      JavaToNativeVideoDecoder(jni, j_primary_decoder);

  VideoDecoder* nativeWrapper =
      CreateVideoDecoderSoftwareFallbackWrapper(std::move(fallback_decoder),
                                                std::move(primary_decoder))
          .release();
    RTC_LOG(LS_ERROR) << "gezhaoyou  cccccccccccc JNI_VideoDecoderFallback_CreateDecoder.";
  return jlongFromPointer(nativeWrapper);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 */
public class VideoDecoderFallback extends WrappedNativeVideoDecoder {
  private final VideoDecoder fallback;
  private final VideoDecoder primary;

  public VideoDecoderFallback(VideoDecoder fallback, VideoDecoder primary) {
    this.fallback = fallback;
    this.primary = primary;
  }
	// 这里创建
  @Override
  public long createNativeVideoDecoder() {
    return nativeCreateDecoder(fallback, primary);
  }

  private static native long nativeCreateDecoder(VideoDecoder fallback, VideoDecoder primary);
}

调用创建 软/硬解码器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  @Override
  public @Nullable VideoDecoder createDecoder(VideoCodecInfo codecType) {
    VideoDecoder softwareDecoder = softwareVideoDecoderFactory.createDecoder(codecType);
    final VideoDecoder hardwareDecoder = hardwareVideoDecoderFactory.createDecoder(codecType);
    if (softwareDecoder == null && platformSoftwareVideoDecoderFactory != null) {
      softwareDecoder = platformSoftwareVideoDecoderFactory.createDecoder(codecType);
    }
    if (hardwareDecoder != null && softwareDecoder != null) {
      // Both hardware and software supported, wrap it in a software fallback
      return new VideoDecoderFallback(
          /* fallback= */ softwareDecoder, /* primary= */ hardwareDecoder);
    }
    return hardwareDecoder != null ? hardwareDecoder : softwareDecoder;
  }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  @Override
  public VideoDecoder createDecoder(VideoCodecInfo codecInfo) {
    String codecName = codecInfo.getName();

    if (codecName.equalsIgnoreCase(VideoCodecMimeType.VP8.name())) {
      return new LibvpxVp8Decoder();
    }
    if (codecName.equalsIgnoreCase(VideoCodecMimeType.VP9.name())
        && LibvpxVp9Decoder.nativeIsSupported()) {
      return new LibvpxVp9Decoder();
    }
    if (codecName.equalsIgnoreCase(VideoCodecMimeType.AV1.name())
        && LibaomAv1Decoder.nativeIsSupported()) {
      return new LibaomAv1Decoder();
    }

    return null;
  }

以创建 libav1为例:

1
2
3
4
5
6
7
8
9
10
public class LibaomAv1Decoder extends WrappedNativeVideoDecoder {
  @Override
  public long createNativeVideoDecoder() {
    return nativeCreateDecoder();
  }

  static native long nativeCreateDecoder();

  static native boolean nativeIsSupported();
}

native 层创AV1建软解:

1
2
3
4
static jlong JNI_Dav1dDecoder_CreateDecoder(JNIEnv* jni) {
  return jlongFromPointer(webrtc::CreateDav1dDecoder().release());
}

1
2
3
std::unique_ptr<VideoDecoder> CreateDav1dDecoder() {
  return std::make_unique<Dav1dDecoder>();
}

platformSoftwareVideoDecoderFactory

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  @Nullable
  @Override
  public VideoDecoder createDecoder(VideoCodecInfo codecType) {
    VideoCodecMimeType type = VideoCodecMimeType.valueOf(codecType.getName());
    MediaCodecInfo info = findCodecForType(type);

    if (info == null) {
      return null;
    }

    CodecCapabilities capabilities = info.getCapabilitiesForType(type.mimeType());
    return new AndroidVideoDecoder(new MediaCodecWrapperFactoryImpl(), info.getName(), type,
        MediaCodecUtils.selectColorFormat(MediaCodecUtils.DECODER_COLOR_FORMATS, capabilities),
        sharedContext);
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
std::unique_ptr<VideoDecoder> InternalDecoderFactory::CreateVideoDecoder(
    const SdpVideoFormat& format) {
       __android_log_print(ANDROID_LOG_ERROR,"gezhaoyou","gezhaoyou 333332222222");
  if (!format.IsCodecInList(GetSupportedFormats())) {
    RTC_LOG(LS_WARNING) << "Trying to create decoder for unsupported format. "
                        << format.ToString();
    return nullptr;
  }
  __android_log_print(ANDROID_LOG_ERROR,"gezhaoyou","gezhaoyou bb xxxxxxxxxxx:%s", format.name.c_str());
  if (absl::EqualsIgnoreCase(format.name, cricket::kVp8CodecName))
    return VP8Decoder::Create();
  if (absl::EqualsIgnoreCase(format.name, cricket::kVp9CodecName))
    return VP9Decoder::Create();
  if (absl::EqualsIgnoreCase(format.name, cricket::kH264CodecName))
    return H264Decoder::Create();
  if (absl::EqualsIgnoreCase(format.name, cricket::kH265CodecName)) {
    RTC_LOG(LS_ERROR) << "gezhaoyou create H265 decoder. ";
     __android_log_print(ANDROID_LOG_ERROR,"gezhaoyou","gezhaoyou ccccxxxxxxxxaaaaaa");
    return H264Decoder::Create();
  }

  if (absl::EqualsIgnoreCase(format.name, cricket::kAv1CodecName) &&
      kDav1dIsIncluded && !field_trial::IsDisabled(kDav1dFieldTrial)) {
    return CreateDav1dDecoder();
  }

  if (absl::EqualsIgnoreCase(format.name, cricket::kAv1CodecName) &&
      kIsLibaomAv1DecoderSupported) {
    return CreateLibaomAv1Decoder();
  }

  RTC_DCHECK_NOTREACHED();
  return nullptr;
}
本文由作者按照 CC BY 4.0 进行授权