mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-19 00:27:51 +01:00

Change log:ba1ae79f58..6f9b3224db
Full diff:ba1ae79f58..6f9b3224db
Changed dependencies * fuchsia_version: version:21.20240620.2.1..version:22.20240801.2.1 * reclient_version: re_client_version:0.148.0.41b09b51-gomaip..re_client_version:0.155.0.f89f6fe3-gomaip * src/base:aa6dbe6d6a..f092508cc2
* src/build:5bce81deee..a0e5713502
* src/buildtools:94d7b86a83..1926812554
* src/buildtools/linux64: git_revision:b2afae122eeb6ce09c52d63f67dc53fc517dbdc8..git_revision:05eed8f6252e2dd6b555e0b65192ef03e2c4a276 * src/buildtools/mac: git_revision:b2afae122eeb6ce09c52d63f67dc53fc517dbdc8..git_revision:05eed8f6252e2dd6b555e0b65192ef03e2c4a276 * src/buildtools/reclient: re_client_version:0.148.0.41b09b51-gomaip..re_client_version:0.155.0.f89f6fe3-gomaip * src/buildtools/win: git_revision:b2afae122eeb6ce09c52d63f67dc53fc517dbdc8..git_revision:05eed8f6252e2dd6b555e0b65192ef03e2c4a276 * src/ios:9e33110a5d..a603c11cfa
* src/testing:a1b47952f3..7605e1a3e3
* src/third_party:91945cadc2..49b13d9832
* src/third_party/android_build_tools/aapt2: G1S0vNnfv3f8FD-9mH5RFSUiK-mnSwri_IdiVQKwLP0C..cfGQ9GV4juNnGZIPzTmaL3ehiZM1hs6UsB5HUA8fT6oC * src/third_party/android_build_tools/bundletool: CaAT7TJbLQC0LVo1i2TXtaMjK4SZBQ33n-s6DcBbZfgC..sZ24OFOduSafn8fvR3ajsGS6KP_oS_Tq0Cw3SA8XiD0C * src/third_party/android_build_tools/manifest_merger: 8yUA9fKPOvtc2p3lVEA3l885a1V4-CXZuKt6xAbdR4AC..xoWqP0Bmz9ReU5nL9ems2x3Ir4Ir3PMTLyba0Ibs824C * src/third_party/android_sdk/public: mU9jm4LkManzjSzRquV1UIA7fHBZ2pK7NtbCXxoVnVUC..fv6JzkTqfxfIbmsRC8u1b2y0EQO7yQDMDzY3-g0NVu4C * src/third_party/android_system_sdk: 4QeolYaSKWBtVTgzJU4tHUfzA9OJTDM8YUcD426IctwC..XzzECzCzGLrccJS1U-HdmM5VMh9BotgQ_mWhFQ464PwC * src/third_party/android_toolchain/ndk: wpJvg81kuXdMM66r_l9Doa-pLfR6S26Jd1x40LpwWEoC..Idl-vYnWGnM8K3XJhM3h6zjYVDXlnljVz3FE00V9IM8C * src/third_party/androidx/cipd: Z7XlkD_7fIL0GqryXCpnM2SunziZ3jWsNCO2UIOAheMC..o9-gndsuJRMgUwrhQG8Ozqkmxs-SQt9pn6kzqZmuQYMC * src/third_party/breakpad/breakpad:76788faa4e..1420017c7f
* src/third_party/catapult: https://chromium.googlesource.com/catapult.git/+log/022cd349fe..2feeb46c60 * src/third_party/dav1d/libdav1d:92f592ed10..2355eeb8f2
* src/third_party/depot_tools:f1c7c96958..75932421da
* src/third_party/ffmpeg:d941d9677b..67060f141b
* src/third_party/flatbuffers/src:6ede1ccc9e..fb9afbafc7
* src/third_party/freetype/src:73720c7c99..ec378cecaf
* src/third_party/googletest/src:1d17ea141d..ff233bdd4c
* src/third_party/icu:163e29159e..9408c6fd4a
* src/third_party/kotlin_stdlib: _4e0lDaCjMgaNeq2v2olJs_15Ax3PxGfCU9fMt0FTKcC..qtDQdcYfgSh4FeSY3TnkSjnZ5FqCbP1kjk1Zj1m6Jd4C * src/third_party/kotlinc/current: 9KgLQsrBWX4kePu9T7eDB1JknSYIPKmmumTEE70lyHYC..dsxRhKDTq0fkLEZLBAcBOaGkoSlvPe_gpTl3o680x7MC * src/third_party/libaom/source/libaom: https://aomedia.googlesource.com/aom.git/+log/afedaf9da5..d8ef6563e0 * src/third_party/libc++/src:09b99fd8ab..7993b2fda2
* src/third_party/libc++abi/src:bac941ca44..eb6567388e
* src/third_party/libunwind/src:dcc1ffafb5..6db1ccfa71
* src/third_party/libvpx/source/libvpx:253d6365e3..428f3104fa
* src/third_party/openh264/src:09a4f3ec84..478e5ab3ec
* src/third_party/perfetto:f9098afffa..26643fc4e9
* src/third_party/r8: M8rc1oybTkWXWpoImSQ8gAwv6mdEyvAPnQNs6Dus_28C..PXH37yAaLUOxMKapVN58gGbrt4ncdU0of7PVnU1hqlAC * src/third_party/re2/src:6144b62bec..6dcd83d60f
* src/third_party/turbine: xWEBZuFKl1Dvw_zOpabeMkGVYlEllIxK06D-RoC6wUsC..HLBr7iWMO2VeD_WbrAA1eq33jZZCVxvA3noE3LNzSlQC * src/tools:a8fe86b922..1487e03fbb
* src/tools/luci-go: git_revision:6fb4d5d26773ebddeac2c57506324493e4220007..git_revision:be41b8d978e22d396ecb4aa9f50ddc3f25977359 * src/tools/luci-go: git_revision:6fb4d5d26773ebddeac2c57506324493e4220007..git_revision:be41b8d978e22d396ecb4aa9f50ddc3f25977359 Added dependencies * src/third_party/android_deps/cipd/libs/com_google_android_gms_play_services_cast_framework * src/third_party/android_deps/cipd/libs/com_google_android_gms_play_services_location * src/third_party/android_deps/cipd/libs/com_squareup_moshi_moshi * src/third_party/android_deps/cipd/libs/com_android_support_swiperefreshlayout * src/third_party/android_deps/cipd/libs/com_android_support_localbroadcastmanager * src/third_party/android_deps/cipd/libs/com_android_support_support_annotations * src/third_party/android_deps/cipd/libs/org_checkerframework_dataflow_errorprone * src/third_party/android_deps/cipd/libs/com_google_firebase_firebase_encoders * src/third_party/android_deps/cipd/libs/org_robolectric_junit * src/third_party/android_deps/cipd/libs/com_google_firebase_firebase_iid_interop * src/third_party/android_deps/cipd/libs/com_google_firebase_firebase_installations_interop * src/third_party/android_deps/cipd/libs/net_bytebuddy_byte_buddy_agent * src/third_party/android_deps/cipd/libs/org_jetbrains_kotlin_kotlin_parcelize_runtime * src/third_party/android_deps/cipd/libs/org_robolectric_nativeruntime * src/third_party/android_deps/cipd/libs/org_bouncycastle_bcprov_jdk18on * src/third_party/android_deps/cipd/libs/org_robolectric_shadows_versioning * src/third_party/android_deps/cipd/libs/net_ltgt_gradle_incap_incap * src/third_party/android_deps/cipd/libs/com_google_firebase_firebase_annotations * src/third_party/android_deps/cipd/libs/com_google_j2objc_j2objc_annotations * src/third_party/android_deps/cipd/libs/com_google_firebase_firebase_messaging * src/third_party/android_deps/cipd/libs/com_android_support_viewpager * src/third_party/android_deps/cipd/libs/org_robolectric_sandbox * src/third_party/android_deps/cipd/libs/android_arch_lifecycle_livedata_core * src/third_party/android_deps/cipd/libs/com_google_googlejavaformat_google_java_format * src/third_party/android_deps/cipd/libs/com_google_errorprone_error_prone_type_annotations * src/third_party/android_deps/cipd/libs/com_google_firebase_firebase_common * src/third_party/android_deps/cipd/libs/org_checkerframework_checker_compat_qual * src/third_party/android_deps/cipd/libs/com_google_code_findbugs_jsr305 * src/third_party/android_deps/cipd/libs/com_google_auto_value_auto_value_annotations * src/third_party/android_deps/cipd/libs/com_google_android_gms_play_services_auth * src/third_party/android_deps/cipd/libs/com_google_android_play_core_common * src/third_party/android_deps/cipd/libs/com_android_support_cursoradapter * src/third_party/android_deps/cipd/libs/com_google_errorprone_javac * src/third_party/android_deps/cipd/libs/com_google_dagger_dagger * src/third_party/android_deps/cipd/libs/org_jetbrains_kotlinx_kotlinx_coroutines_guava * src/third_party/android_deps/cipd/libs/com_android_support_customview * src/third_party/android_deps/cipd/libs/com_google_android_play_feature_delivery * src/third_party/android_deps/cipd/libs/com_google_android_gms_play_services_base * src/third_party/android_deps/cipd/libs/org_mockito_mockito_subclass * src/third_party/android_deps/cipd/libs/com_google_android_gms_play_services_vision_common * src/third_party/android_deps/cipd/libs/io_grpc_grpc_stub * src/third_party/android_deps/cipd/libs/org_mockito_mockito_core * src/third_party/android_deps/cipd/libs/org_jetbrains_kotlinx_kotlinx_coroutines_android * src/third_party/android_deps/cipd/libs/com_google_firebase_firebase_components * src/third_party/android_deps/cipd/libs/com_google_android_gms_play_services_instantapps * src/third_party/android_deps/cipd/libs/net_bytebuddy_byte_buddy * src/third_party/android_deps/cipd/libs/org_jetbrains_kotlinx_atomicfu_jvm * src/third_party/android_deps/cipd/libs/io_perfmark_perfmark_api * src/third_party/android_deps/cipd/libs/android_arch_lifecycle_livedata * src/third_party/android_deps/cipd/libs/com_github_ben_manes_caffeine_caffeine * src/third_party/android_deps/cipd/libs/com_google_errorprone_error_prone_check_api * src/third_party/android_deps/cipd/libs/com_google_android_gms_play_services_cloud_messaging * src/third_party/android_deps/cipd/libs/com_googlecode_java_diff_utils_diffutils * src/third_party/android_deps/cipd/libs/io_grpc_grpc_binder * src/third_party/android_deps/cipd/libs/com_google_android_gms_play_services_phenotype * src/third_party/android_deps/cipd/libs/com_google_android_gms_play_services_cast * src/third_party/android_deps/cipd/libs/com_google_auto_service_auto_service_annotations * src/third_party/android_deps/cipd/libs/org_checkerframework_checker_qual * src/third_party/android_deps/cipd/libs/javax_inject_javax_inject * src/third_party/android_deps/cipd/libs/com_google_android_gms_play_services_identity_credentials * src/third_party/android_deps/cipd/libs/com_google_firebase_firebase_encoders_json * src/third_party/android_deps/cipd/libs/com_google_android_gms_play_services_flags * src/third_party/android_deps/cipd/libs/com_android_tools_sdk_common * src/third_party/android_deps/cipd/libs/com_google_android_gms_play_services_tasks * src/third_party/android_deps/cipd/libs/com_google_protobuf_protobuf_javalite * src/third_party/android_deps/cipd/libs/org_ow2_asm_asm * src/third_party/android_deps/cipd/libs/com_squareup_wire_wire_runtime_jvm * src/third_party/android_deps/cipd/libs/com_google_android_gms_play_services_auth_base * src/third_party/android_deps/cipd/libs/org_robolectric_shadows_framework * src/third_party/android_deps/cipd/libs/org_robolectric_utils * src/third_party/android_deps/cipd/libs/org_ow2_asm_asm_util * src/third_party/android_deps/cipd/libs/android_arch_lifecycle_runtime * src/third_party/android_deps/cipd/libs/org_robolectric_robolectric * src/third_party/android_deps/cipd/libs/org_mockito_mockito_android * src/third_party/android_deps/cipd/libs/org_robolectric_pluginapi * src/third_party/android_deps/cipd/libs/com_google_protobuf_protobuf_java * src/third_party/android_deps/cipd/libs/com_android_support_support_core_utils * src/third_party/android_deps/cipd/libs/org_checkerframework_checker_util * src/third_party/android_deps/cipd/libs/com_android_support_support_core_ui * src/third_party/android_deps/cipd/libs/com_android_support_asynclayoutinflater * src/third_party/android_deps/cipd/libs/org_objenesis_objenesis * src/third_party/android_deps/cipd/libs/com_android_support_print * src/third_party/android_deps/cipd/libs/com_google_android_datatransport_transport_api * src/third_party/android_deps/cipd/libs/com_google_android_gms_play_services_vision * src/third_party/android_deps/cipd/libs/com_android_tools_layoutlib_layoutlib_api * src/third_party/android_deps/cipd/libs/org_robolectric_annotations * src/third_party/android_deps/cipd/libs/com_google_dagger_dagger_spi * src/third_party/android_deps/cipd/libs/com_google_errorprone_error_prone_annotations * src/third_party/android_deps/cipd/libs/android_arch_core_runtime * src/third_party/android_deps/cipd/libs/com_google_firebase_firebase_iid * src/third_party/android_deps/cipd/libs/com_squareup_moshi_moshi_adapters * src/third_party/android_deps/cipd/libs/com_google_android_annotations * src/third_party/android_deps/cipd/libs/com_squareup_javapoet * src/third_party/android_deps/cipd/libs/com_google_errorprone_error_prone_annotation * src/third_party/android_deps/cipd/libs/org_eclipse_jgit_org_eclipse_jgit * src/third_party/android_deps/cipd/libs/com_google_android_gms_play_services_stats * src/third_party/android_deps/cipd/libs/com_google_dagger_dagger_producers * src/third_party/android_deps/cipd/libs/org_hamcrest_hamcrest * src/third_party/android_deps/cipd/libs/com_android_support_drawerlayout * src/third_party/android_deps/cipd/libs/com_google_errorprone_error_prone_core * src/third_party/android_deps/cipd/libs/org_robolectric_plugins_maven_dependency_resolver * src/third_party/android_deps/cipd/libs/com_android_support_interpolator * src/third_party/android_deps/cipd/libs/io_grpc_grpc_protobuf_lite * src/third_party/android_deps/cipd/libs/com_google_code_gson_gson * src/third_party/android_deps/cipd/libs/android_arch_core_common * src/third_party/android_deps/cipd/libs/com_google_guava_guava * src/third_party/android_deps/cipd/libs/com_android_support_versionedparcelable * src/third_party/android_deps/cipd/libs/org_jetbrains_kotlin_kotlin_android_extensions_runtime * src/third_party/android_deps/cipd/libs/com_google_android_gms_play_services_basement * src/third_party/android_deps/cipd/libs/org_robolectric_resources * src/third_party/android_deps/cipd/libs/com_google_dagger_dagger_compiler * src/third_party/android_deps/cipd/libs/javax_annotation_javax_annotation_api * src/third_party/android_deps/cipd/libs/io_grpc_grpc_context * src/third_party/android_deps/cipd/libs/org_ccil_cowan_tagsoup_tagsoup * src/third_party/android_deps/cipd/libs/io_grpc_grpc_api * src/third_party/android_deps/cipd/libs/org_ow2_asm_asm_commons * src/third_party/android_deps/cipd/libs/com_squareup_javawriter * src/third_party/android_deps/cipd/libs/com_android_support_slidingpanelayout * src/third_party/android_deps/cipd/libs/com_google_android_apps_common_testing_accessibility_framework_accessibility_test_framework * src/third_party/android_deps/cipd/libs/com_android_support_support_compat * src/third_party/android_deps/cipd/libs/org_ow2_asm_asm_analysis * src/third_party/android_deps/cipd/libs/org_jetbrains_kotlinx_kotlinx_coroutines_core_jvm * src/third_party/android_deps/cipd/libs/org_robolectric_utils_reflector * src/third_party/android_deps/cipd/libs/com_google_auto_auto_common * src/third_party/android_deps/cipd/libs/com_github_kevinstern_software_and_algorithms * src/third_party/android_deps/cipd/libs/org_jetbrains_kotlinx_kotlinx_metadata_jvm * src/third_party/android_deps/cipd/libs/org_conscrypt_conscrypt_openjdk_uber * src/third_party/android_deps/cipd/libs/com_android_support_documentfile * src/third_party/android_deps/cipd/libs/io_grpc_grpc_core * src/third_party/android_deps/cipd/libs/com_google_android_gms_play_services_iid * src/third_party/android_deps/cipd/libs/org_jetbrains_kotlin_kotlin_stdlib_jdk7 * src/third_party/android_deps/cipd/libs/org_jsoup_jsoup * src/third_party/android_deps/cipd/libs/com_google_firebase_firebase_measurement_connector * src/third_party/android_deps/cipd/libs/android_arch_lifecycle_common * src/third_party/android_deps/cipd/libs/com_google_errorprone_javac_shaded * src/third_party/android_deps/cipd/libs/com_google_firebase_firebase_installations * src/third_party/android_deps/cipd/libs/com_google_android_material_material * src/third_party/android_deps/cipd/libs/com_google_android_gms_play_services_gcm * src/third_party/android_deps/cipd/libs/com_squareup_okio_okio_jvm * src/third_party/android_deps/cipd/libs/org_codehaus_mojo_animal_sniffer_annotations * src/third_party/android_deps/cipd/libs/com_google_android_gms_play_services_auth_api_phone * src/third_party/android_deps/cipd/libs/com_google_android_gms_play_services_clearcut * src/third_party/android_deps/cipd/libs/org_ow2_asm_asm_tree * src/third_party/android_deps/cipd/libs/com_google_guava_guava_android * src/third_party/android_deps/cipd/libs/com_android_support_collections * src/third_party/android_deps/cipd/libs/com_android_support_coordinatorlayout * src/third_party/android_deps/cipd/libs/io_github_java_diff_utils_java_diff_utils * src/third_party/android_deps/cipd/libs/com_google_guava_failureaccess * src/third_party/android_deps/cipd/libs/org_robolectric_nativeruntime_dist_compat * src/third_party/android_deps/cipd/libs/com_android_tools_common * src/third_party/android_deps/cipd/libs/org_robolectric_shadowapi * src/third_party/android_deps/cipd/libs/com_google_auto_service_auto_service * src/third_party/android_deps/cipd/libs/javax_annotation_jsr250_api * src/third_party/android_deps/cipd/libs/android_arch_lifecycle_viewmodel * src/third_party/android_deps/cipd/libs/org_jetbrains_kotlin_kotlin_stdlib_jdk8 * src/third_party/android_deps/cipd/libs/com_android_support_loader * src/third_party/android_deps/cipd/libs/org_pcollections_pcollections Removed dependencies * src/third_party/android_deps/libs/android_arch_core_common * src/third_party/android_deps/libs/android_arch_core_runtime * src/third_party/android_deps/libs/android_arch_lifecycle_common * src/third_party/android_deps/libs/android_arch_lifecycle_livedata * src/third_party/android_deps/libs/android_arch_lifecycle_livedata_core * src/third_party/android_deps/libs/android_arch_lifecycle_runtime * src/third_party/android_deps/libs/android_arch_lifecycle_viewmodel * src/third_party/android_deps/libs/com_android_support_asynclayoutinflater * src/third_party/android_deps/libs/com_android_support_collections * src/third_party/android_deps/libs/com_android_support_coordinatorlayout * src/third_party/android_deps/libs/com_android_support_cursoradapter * src/third_party/android_deps/libs/com_android_support_customview * src/third_party/android_deps/libs/com_android_support_documentfile * src/third_party/android_deps/libs/com_android_support_drawerlayout * src/third_party/android_deps/libs/com_android_support_interpolator * src/third_party/android_deps/libs/com_android_support_loader * src/third_party/android_deps/libs/com_android_support_localbroadcastmanager * src/third_party/android_deps/libs/com_android_support_print * src/third_party/android_deps/libs/com_android_support_slidingpanelayout * src/third_party/android_deps/libs/com_android_support_support_annotations * src/third_party/android_deps/libs/com_android_support_support_compat * src/third_party/android_deps/libs/com_android_support_support_core_ui * src/third_party/android_deps/libs/com_android_support_support_core_utils * src/third_party/android_deps/libs/com_android_support_swiperefreshlayout * src/third_party/android_deps/libs/com_android_support_versionedparcelable * src/third_party/android_deps/libs/com_android_support_viewpager * src/third_party/android_deps/libs/com_android_tools_common * src/third_party/android_deps/libs/com_android_tools_layoutlib_layoutlib_api * src/third_party/android_deps/libs/com_android_tools_sdk_common * src/third_party/android_deps/libs/com_github_ben_manes_caffeine_caffeine * src/third_party/android_deps/libs/com_github_kevinstern_software_and_algorithms * src/third_party/android_deps/libs/com_google_android_annotations * src/third_party/android_deps/libs/com_google_android_apps_common_testing_accessibility_framework_accessibility_test_framework * src/third_party/android_deps/libs/com_google_android_datatransport_transport_api * src/third_party/android_deps/libs/com_google_android_gms_play_services_auth * src/third_party/android_deps/libs/com_google_android_gms_play_services_auth_api_phone * src/third_party/android_deps/libs/com_google_android_gms_play_services_auth_base * src/third_party/android_deps/libs/com_google_android_gms_play_services_base * src/third_party/android_deps/libs/com_google_android_gms_play_services_basement * src/third_party/android_deps/libs/com_google_android_gms_play_services_cast * src/third_party/android_deps/libs/com_google_android_gms_play_services_cast_framework * src/third_party/android_deps/libs/com_google_android_gms_play_services_clearcut * src/third_party/android_deps/libs/com_google_android_gms_play_services_cloud_messaging * src/third_party/android_deps/libs/com_google_android_gms_play_services_flags * src/third_party/android_deps/libs/com_google_android_gms_play_services_gcm * src/third_party/android_deps/libs/com_google_android_gms_play_services_iid * src/third_party/android_deps/libs/com_google_android_gms_play_services_instantapps * src/third_party/android_deps/libs/com_google_android_gms_play_services_location * src/third_party/android_deps/libs/com_google_android_gms_play_services_phenotype * src/third_party/android_deps/libs/com_google_android_gms_play_services_stats * src/third_party/android_deps/libs/com_google_android_gms_play_services_tasks * src/third_party/android_deps/libs/com_google_android_gms_play_services_vision * src/third_party/android_deps/libs/com_google_android_gms_play_services_vision_common * src/third_party/android_deps/libs/com_google_android_material_material * src/third_party/android_deps/libs/com_google_android_play_core_common * src/third_party/android_deps/libs/com_google_android_play_feature_delivery * src/third_party/android_deps/libs/com_google_auto_auto_common * src/third_party/android_deps/libs/com_google_auto_service_auto_service * src/third_party/android_deps/libs/com_google_auto_service_auto_service_annotations * src/third_party/android_deps/libs/com_google_auto_value_auto_value_annotations * src/third_party/android_deps/libs/com_google_code_findbugs_jsr305 * src/third_party/android_deps/libs/com_google_code_gson_gson * src/third_party/android_deps/libs/com_google_dagger_dagger * src/third_party/android_deps/libs/com_google_dagger_dagger_compiler * src/third_party/android_deps/libs/com_google_dagger_dagger_producers * src/third_party/android_deps/libs/com_google_dagger_dagger_spi * src/third_party/android_deps/libs/com_google_errorprone_error_prone_annotation * src/third_party/android_deps/libs/com_google_errorprone_error_prone_annotations * src/third_party/android_deps/libs/com_google_errorprone_error_prone_check_api * src/third_party/android_deps/libs/com_google_errorprone_error_prone_core * src/third_party/android_deps/libs/com_google_errorprone_error_prone_type_annotations * src/third_party/android_deps/libs/com_google_errorprone_javac * src/third_party/android_deps/libs/com_google_errorprone_javac_shaded * src/third_party/android_deps/libs/com_google_firebase_firebase_annotations * src/third_party/android_deps/libs/com_google_firebase_firebase_common * src/third_party/android_deps/libs/com_google_firebase_firebase_components * src/third_party/android_deps/libs/com_google_firebase_firebase_encoders * src/third_party/android_deps/libs/com_google_firebase_firebase_encoders_json * src/third_party/android_deps/libs/com_google_firebase_firebase_iid * src/third_party/android_deps/libs/com_google_firebase_firebase_iid_interop * src/third_party/android_deps/libs/com_google_firebase_firebase_installations * src/third_party/android_deps/libs/com_google_firebase_firebase_installations_interop * src/third_party/android_deps/libs/com_google_firebase_firebase_measurement_connector * src/third_party/android_deps/libs/com_google_firebase_firebase_messaging * src/third_party/android_deps/libs/com_google_googlejavaformat_google_java_format * src/third_party/android_deps/libs/com_google_guava_failureaccess * src/third_party/android_deps/libs/com_google_guava_guava * src/third_party/android_deps/libs/com_google_guava_guava_android * src/third_party/android_deps/libs/com_google_j2objc_j2objc_annotations * src/third_party/android_deps/libs/com_google_protobuf_protobuf_java * src/third_party/android_deps/libs/com_google_protobuf_protobuf_javalite * src/third_party/android_deps/libs/com_googlecode_java_diff_utils_diffutils * src/third_party/android_deps/libs/com_squareup_javapoet * src/third_party/android_deps/libs/com_squareup_javawriter * src/third_party/android_deps/libs/com_squareup_moshi_moshi * src/third_party/android_deps/libs/com_squareup_moshi_moshi_adapters * src/third_party/android_deps/libs/com_squareup_okio_okio_jvm * src/third_party/android_deps/libs/com_squareup_wire_wire_runtime_jvm * src/third_party/android_deps/libs/io_github_java_diff_utils_java_diff_utils * src/third_party/android_deps/libs/io_grpc_grpc_api * src/third_party/android_deps/libs/io_grpc_grpc_binder * src/third_party/android_deps/libs/io_grpc_grpc_context * src/third_party/android_deps/libs/io_grpc_grpc_core * src/third_party/android_deps/libs/io_grpc_grpc_protobuf_lite * src/third_party/android_deps/libs/io_grpc_grpc_stub * src/third_party/android_deps/libs/io_perfmark_perfmark_api * src/third_party/android_deps/libs/javax_annotation_javax_annotation_api * src/third_party/android_deps/libs/javax_annotation_jsr250_api * src/third_party/android_deps/libs/javax_inject_javax_inject * src/third_party/android_deps/libs/net_bytebuddy_byte_buddy * src/third_party/android_deps/libs/net_bytebuddy_byte_buddy_agent * src/third_party/android_deps/libs/net_ltgt_gradle_incap_incap * src/third_party/android_deps/libs/org_bouncycastle_bcprov_jdk18on * src/third_party/android_deps/libs/org_ccil_cowan_tagsoup_tagsoup * src/third_party/android_deps/libs/org_checkerframework_checker_compat_qual * src/third_party/android_deps/libs/org_checkerframework_checker_qual * src/third_party/android_deps/libs/org_checkerframework_checker_util * src/third_party/android_deps/libs/org_checkerframework_dataflow_errorprone * src/third_party/android_deps/libs/org_codehaus_mojo_animal_sniffer_annotations * src/third_party/android_deps/libs/org_conscrypt_conscrypt_openjdk_uber * src/third_party/android_deps/libs/org_eclipse_jgit_org_eclipse_jgit * src/third_party/android_deps/libs/org_hamcrest_hamcrest * src/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_android_extensions_runtime * src/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_parcelize_runtime * src/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib_jdk7 * src/third_party/android_deps/libs/org_jetbrains_kotlin_kotlin_stdlib_jdk8 * src/third_party/android_deps/libs/org_jetbrains_kotlinx_atomicfu_jvm * src/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_coroutines_android * src/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_coroutines_core_jvm * src/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_coroutines_guava * src/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_metadata_jvm * src/third_party/android_deps/libs/org_jsoup_jsoup * src/third_party/android_deps/libs/org_mockito_mockito_android * src/third_party/android_deps/libs/org_mockito_mockito_core * src/third_party/android_deps/libs/org_mockito_mockito_subclass * src/third_party/android_deps/libs/org_objenesis_objenesis * src/third_party/android_deps/libs/org_ow2_asm_asm * src/third_party/android_deps/libs/org_ow2_asm_asm_analysis * src/third_party/android_deps/libs/org_ow2_asm_asm_commons * src/third_party/android_deps/libs/org_ow2_asm_asm_tree * src/third_party/android_deps/libs/org_ow2_asm_asm_util * src/third_party/android_deps/libs/org_pcollections_pcollections * src/third_party/android_deps/libs/org_robolectric_annotations * src/third_party/android_deps/libs/org_robolectric_junit * src/third_party/android_deps/libs/org_robolectric_nativeruntime * src/third_party/android_deps/libs/org_robolectric_nativeruntime_dist_compat * src/third_party/android_deps/libs/org_robolectric_pluginapi * src/third_party/android_deps/libs/org_robolectric_plugins_maven_dependency_resolver * src/third_party/android_deps/libs/org_robolectric_resources * src/third_party/android_deps/libs/org_robolectric_robolectric * src/third_party/android_deps/libs/org_robolectric_sandbox * src/third_party/android_deps/libs/org_robolectric_shadowapi * src/third_party/android_deps/libs/org_robolectric_shadows_framework * src/third_party/android_deps/libs/org_robolectric_shadows_versioning * src/third_party/android_deps/libs/org_robolectric_utils * src/third_party/android_deps/libs/org_robolectric_utils_reflector DEPS diff:ba1ae79f58..6f9b3224db
/DEPS Clang version changed llvmorg-19-init-14561-gecea8371:llvmorg-20-init-1009-g7088a5ed Details:ba1ae79f58..6f9b3224db
/tools/clang/scripts/update.py BUG=b/351773023 Change-Id: I1ed351ae305262cc34fccc67bcbd748637b803f4 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/358880 Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Reviewed-by: Christoffer Dewerin <jansson@webrtc.org> Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org> Cr-Commit-Position: refs/heads/main@{#42744}
1248 lines
44 KiB
C++
1248 lines
44 KiB
C++
/*
|
|
* Copyright (c) 2021 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 "modules/video_coding/h26x_packet_buffer.h"
|
|
|
|
#include <cstring>
|
|
#include <limits>
|
|
#include <ostream>
|
|
#include <string>
|
|
#include <utility>
|
|
|
|
#include "api/array_view.h"
|
|
#include "api/video/render_resolution.h"
|
|
#include "common_video/h264/h264_common.h"
|
|
#include "rtc_base/system/unused.h"
|
|
#include "test/gmock.h"
|
|
#include "test/gtest.h"
|
|
#ifdef RTC_ENABLE_H265
|
|
#include "common_video/h265/h265_common.h"
|
|
#endif
|
|
|
|
namespace webrtc {
|
|
namespace {
|
|
|
|
using ::testing::ElementsAreArray;
|
|
using ::testing::Eq;
|
|
using ::testing::IsEmpty;
|
|
using ::testing::SizeIs;
|
|
|
|
using H264::NaluType::kAud;
|
|
using H264::NaluType::kFuA;
|
|
using H264::NaluType::kIdr;
|
|
using H264::NaluType::kPps;
|
|
using H264::NaluType::kSlice;
|
|
using H264::NaluType::kSps;
|
|
using H264::NaluType::kStapA;
|
|
|
|
constexpr int kBufferSize = 2048;
|
|
// Example sprop string from https://tools.ietf.org/html/rfc3984.
|
|
const char kExampleSpropString[] = "Z0IACpZTBYmI,aMljiA==";
|
|
static const std::vector<uint8_t> kExampleSpropRawSps{
|
|
0x67, 0x42, 0x00, 0x0A, 0x96, 0x53, 0x05, 0x89, 0x88};
|
|
static const std::vector<uint8_t> kExampleSpropRawPps{0x68, 0xC9, 0x63, 0x88};
|
|
|
|
std::vector<uint8_t> StartCode() {
|
|
return {0, 0, 0, 1};
|
|
}
|
|
|
|
NaluInfo MakeNaluInfo(uint8_t type) {
|
|
NaluInfo res;
|
|
res.type = type;
|
|
res.sps_id = -1;
|
|
res.pps_id = -1;
|
|
return res;
|
|
}
|
|
|
|
class H264Packet {
|
|
public:
|
|
explicit H264Packet(H264PacketizationTypes type);
|
|
|
|
H264Packet& Idr(std::vector<uint8_t> payload = {9, 9, 9}, int pps_id = -1);
|
|
H264Packet& Slice(std::vector<uint8_t> payload = {9, 9, 9});
|
|
H264Packet& Sps(std::vector<uint8_t> payload = {9, 9, 9}, int sps_id = -1);
|
|
H264Packet& SpsWithResolution(RenderResolution resolution,
|
|
std::vector<uint8_t> payload = {9, 9, 9});
|
|
H264Packet& Pps(std::vector<uint8_t> payload = {9, 9, 9},
|
|
int pps_id = -1,
|
|
int sps_id = -1);
|
|
H264Packet& Aud();
|
|
H264Packet& Marker();
|
|
H264Packet& AsFirstFragment();
|
|
H264Packet& Time(uint32_t rtp_timestamp);
|
|
H264Packet& SeqNum(int64_t rtp_seq_num);
|
|
|
|
std::unique_ptr<H26xPacketBuffer::Packet> Build();
|
|
|
|
private:
|
|
rtc::CopyOnWriteBuffer BuildFuaPayload() const;
|
|
rtc::CopyOnWriteBuffer BuildSingleNaluPayload() const;
|
|
rtc::CopyOnWriteBuffer BuildStapAPayload() const;
|
|
|
|
RTPVideoHeaderH264& H264Header() {
|
|
return absl::get<RTPVideoHeaderH264>(video_header_.video_type_header);
|
|
}
|
|
const RTPVideoHeaderH264& H264Header() const {
|
|
return absl::get<RTPVideoHeaderH264>(video_header_.video_type_header);
|
|
}
|
|
|
|
H264PacketizationTypes type_;
|
|
RTPVideoHeader video_header_;
|
|
bool first_fragment_ = false;
|
|
bool marker_bit_ = false;
|
|
uint32_t rtp_timestamp_ = 0;
|
|
int64_t rtp_seq_num_ = 0;
|
|
std::vector<std::vector<uint8_t>> nalu_payloads_;
|
|
};
|
|
|
|
H264Packet::H264Packet(H264PacketizationTypes type) : type_(type) {
|
|
video_header_.video_type_header.emplace<RTPVideoHeaderH264>();
|
|
}
|
|
|
|
H264Packet& H264Packet::Idr(std::vector<uint8_t> payload, int pps_id) {
|
|
auto& h264_header = H264Header();
|
|
auto nalu_info = MakeNaluInfo(kIdr);
|
|
nalu_info.pps_id = pps_id;
|
|
h264_header.nalus.push_back(nalu_info);
|
|
nalu_payloads_.push_back(std::move(payload));
|
|
return *this;
|
|
}
|
|
|
|
H264Packet& H264Packet::Slice(std::vector<uint8_t> payload) {
|
|
auto& h264_header = H264Header();
|
|
h264_header.nalus.push_back(MakeNaluInfo(kSlice));
|
|
nalu_payloads_.push_back(std::move(payload));
|
|
return *this;
|
|
}
|
|
|
|
H264Packet& H264Packet::Sps(std::vector<uint8_t> payload, int sps_id) {
|
|
auto& h264_header = H264Header();
|
|
auto nalu_info = MakeNaluInfo(kSps);
|
|
nalu_info.pps_id = sps_id;
|
|
h264_header.nalus.push_back(nalu_info);
|
|
nalu_payloads_.push_back(std::move(payload));
|
|
return *this;
|
|
}
|
|
|
|
H264Packet& H264Packet::SpsWithResolution(RenderResolution resolution,
|
|
std::vector<uint8_t> payload) {
|
|
auto& h264_header = H264Header();
|
|
h264_header.nalus.push_back(MakeNaluInfo(kSps));
|
|
video_header_.width = resolution.Width();
|
|
video_header_.height = resolution.Height();
|
|
nalu_payloads_.push_back(std::move(payload));
|
|
return *this;
|
|
}
|
|
|
|
H264Packet& H264Packet::Pps(std::vector<uint8_t> payload,
|
|
int pps_id,
|
|
int sps_id) {
|
|
auto& h264_header = H264Header();
|
|
auto nalu_info = MakeNaluInfo(kPps);
|
|
nalu_info.pps_id = pps_id;
|
|
nalu_info.sps_id = sps_id;
|
|
h264_header.nalus.push_back(nalu_info);
|
|
nalu_payloads_.push_back(std::move(payload));
|
|
return *this;
|
|
}
|
|
|
|
H264Packet& H264Packet::Aud() {
|
|
auto& h264_header = H264Header();
|
|
h264_header.nalus.push_back(MakeNaluInfo(kAud));
|
|
nalu_payloads_.push_back({});
|
|
return *this;
|
|
}
|
|
|
|
H264Packet& H264Packet::Marker() {
|
|
marker_bit_ = true;
|
|
return *this;
|
|
}
|
|
|
|
H264Packet& H264Packet::AsFirstFragment() {
|
|
first_fragment_ = true;
|
|
return *this;
|
|
}
|
|
|
|
H264Packet& H264Packet::Time(uint32_t rtp_timestamp) {
|
|
rtp_timestamp_ = rtp_timestamp;
|
|
return *this;
|
|
}
|
|
|
|
H264Packet& H264Packet::SeqNum(int64_t rtp_seq_num) {
|
|
rtp_seq_num_ = rtp_seq_num;
|
|
return *this;
|
|
}
|
|
|
|
std::unique_ptr<H26xPacketBuffer::Packet> H264Packet::Build() {
|
|
auto res = std::make_unique<H26xPacketBuffer::Packet>();
|
|
|
|
auto& h264_header = H264Header();
|
|
switch (type_) {
|
|
case kH264FuA: {
|
|
RTC_CHECK_EQ(h264_header.nalus.size(), 1);
|
|
res->video_payload = BuildFuaPayload();
|
|
break;
|
|
}
|
|
case kH264SingleNalu: {
|
|
RTC_CHECK_EQ(h264_header.nalus.size(), 1);
|
|
res->video_payload = BuildSingleNaluPayload();
|
|
break;
|
|
}
|
|
case kH264StapA: {
|
|
RTC_CHECK_GT(h264_header.nalus.size(), 1);
|
|
res->video_payload = BuildStapAPayload();
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (type_ == kH264FuA && !first_fragment_) {
|
|
h264_header.nalus.clear();
|
|
}
|
|
|
|
h264_header.packetization_type = type_;
|
|
res->marker_bit = marker_bit_;
|
|
res->video_header = video_header_;
|
|
res->timestamp = rtp_timestamp_;
|
|
res->sequence_number = rtp_seq_num_;
|
|
res->video_header.codec = kVideoCodecH264;
|
|
|
|
return res;
|
|
}
|
|
|
|
rtc::CopyOnWriteBuffer H264Packet::BuildFuaPayload() const {
|
|
return rtc::CopyOnWriteBuffer(nalu_payloads_[0]);
|
|
}
|
|
|
|
rtc::CopyOnWriteBuffer H264Packet::BuildSingleNaluPayload() const {
|
|
rtc::CopyOnWriteBuffer res;
|
|
auto& h264_header = H264Header();
|
|
res.AppendData(&h264_header.nalus[0].type, 1);
|
|
res.AppendData(nalu_payloads_[0]);
|
|
return res;
|
|
}
|
|
|
|
rtc::CopyOnWriteBuffer H264Packet::BuildStapAPayload() const {
|
|
rtc::CopyOnWriteBuffer res;
|
|
|
|
const uint8_t indicator = H264::NaluType::kStapA;
|
|
res.AppendData(&indicator, 1);
|
|
|
|
auto& h264_header = H264Header();
|
|
for (size_t i = 0; i < h264_header.nalus.size(); ++i) {
|
|
// The two first bytes indicates the nalu segment size.
|
|
uint8_t length_as_array[2] = {
|
|
0, static_cast<uint8_t>(nalu_payloads_[i].size() + 1)};
|
|
res.AppendData(length_as_array);
|
|
|
|
res.AppendData(&h264_header.nalus[i].type, 1);
|
|
res.AppendData(nalu_payloads_[i]);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
#ifdef RTC_ENABLE_H265
|
|
class H265Packet {
|
|
public:
|
|
H265Packet() = default;
|
|
|
|
H265Packet& Idr(std::vector<uint8_t> payload = {9, 9, 9});
|
|
H265Packet& Slice(H265::NaluType type,
|
|
std::vector<uint8_t> payload = {9, 9, 9});
|
|
H265Packet& Vps(std::vector<uint8_t> payload = {9, 9, 9});
|
|
H265Packet& Sps(std::vector<uint8_t> payload = {9, 9, 9});
|
|
H265Packet& SpsWithResolution(RenderResolution resolution,
|
|
std::vector<uint8_t> payload = {9, 9, 9});
|
|
H265Packet& Pps(std::vector<uint8_t> payload = {9, 9, 9});
|
|
H265Packet& Aud();
|
|
H265Packet& Marker();
|
|
H265Packet& AsFirstFragment();
|
|
H265Packet& Time(uint32_t rtp_timestamp);
|
|
H265Packet& SeqNum(int64_t rtp_seq_num);
|
|
|
|
std::unique_ptr<H26xPacketBuffer::Packet> Build();
|
|
|
|
private:
|
|
H265Packet& StartCode();
|
|
|
|
RTPVideoHeader video_header_;
|
|
bool first_fragment_ = false;
|
|
bool marker_bit_ = false;
|
|
uint32_t rtp_timestamp_ = 0;
|
|
uint16_t rtp_seq_num_ = 0;
|
|
std::vector<std::vector<uint8_t>> nalu_payloads_;
|
|
};
|
|
|
|
H265Packet& H265Packet::Idr(std::vector<uint8_t> payload) {
|
|
return Slice(H265::NaluType::kIdrNLp, std::move(payload));
|
|
}
|
|
|
|
H265Packet& H265Packet::Slice(H265::NaluType type,
|
|
std::vector<uint8_t> payload) {
|
|
StartCode();
|
|
// Nalu header. Assume layer ID is 0 and TID is 2.
|
|
nalu_payloads_.push_back({static_cast<uint8_t>(type << 1), 0x02});
|
|
nalu_payloads_.push_back(std::move(payload));
|
|
return *this;
|
|
}
|
|
|
|
H265Packet& H265Packet::Vps(std::vector<uint8_t> payload) {
|
|
return Slice(H265::NaluType::kVps, std::move(payload));
|
|
}
|
|
|
|
H265Packet& H265Packet::Sps(std::vector<uint8_t> payload) {
|
|
return Slice(H265::NaluType::kSps, std::move(payload));
|
|
}
|
|
|
|
H265Packet& H265Packet::SpsWithResolution(RenderResolution resolution,
|
|
std::vector<uint8_t> payload) {
|
|
video_header_.width = resolution.Width();
|
|
video_header_.height = resolution.Height();
|
|
return Sps(std::move(payload));
|
|
}
|
|
|
|
H265Packet& H265Packet::Pps(std::vector<uint8_t> payload) {
|
|
return Slice(H265::NaluType::kPps, std::move(payload));
|
|
}
|
|
|
|
H265Packet& H265Packet::Aud() {
|
|
return Slice(H265::NaluType::kAud, {});
|
|
}
|
|
|
|
H265Packet& H265Packet::Marker() {
|
|
marker_bit_ = true;
|
|
return *this;
|
|
}
|
|
|
|
H265Packet& H265Packet::StartCode() {
|
|
nalu_payloads_.push_back({0x00, 0x00, 0x00, 0x01});
|
|
return *this;
|
|
}
|
|
|
|
std::unique_ptr<H26xPacketBuffer::Packet> H265Packet::Build() {
|
|
auto res = std::make_unique<H26xPacketBuffer::Packet>();
|
|
res->marker_bit = marker_bit_;
|
|
res->video_header = video_header_;
|
|
res->timestamp = rtp_timestamp_;
|
|
res->sequence_number = rtp_seq_num_;
|
|
res->video_header.codec = kVideoCodecH265;
|
|
res->video_payload = rtc::CopyOnWriteBuffer();
|
|
for (const auto& payload : nalu_payloads_) {
|
|
res->video_payload.AppendData(payload);
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
H265Packet& H265Packet::AsFirstFragment() {
|
|
first_fragment_ = true;
|
|
return *this;
|
|
}
|
|
|
|
H265Packet& H265Packet::Time(uint32_t rtp_timestamp) {
|
|
rtp_timestamp_ = rtp_timestamp;
|
|
return *this;
|
|
}
|
|
|
|
H265Packet& H265Packet::SeqNum(int64_t rtp_seq_num) {
|
|
rtp_seq_num_ = rtp_seq_num;
|
|
return *this;
|
|
}
|
|
#endif
|
|
|
|
rtc::ArrayView<const uint8_t> PacketPayload(
|
|
const std::unique_ptr<H26xPacketBuffer::Packet>& packet) {
|
|
return packet->video_payload;
|
|
}
|
|
|
|
std::vector<uint8_t> FlatVector(
|
|
const std::vector<std::vector<uint8_t>>& elems) {
|
|
std::vector<uint8_t> res;
|
|
for (const auto& elem : elems) {
|
|
res.insert(res.end(), elem.begin(), elem.end());
|
|
}
|
|
return res;
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, IdrOnlyKeyframeWithSprop) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/true);
|
|
packet_buffer.SetSpropParameterSets(kExampleSpropString);
|
|
|
|
auto packets =
|
|
packet_buffer
|
|
.InsertPacket(
|
|
H264Packet(kH264SingleNalu).Idr({1, 2, 3}, 0).Marker().Build())
|
|
.packets;
|
|
EXPECT_THAT(packets, SizeIs(1));
|
|
EXPECT_THAT(PacketPayload(packets[0]),
|
|
ElementsAreArray(FlatVector({StartCode(),
|
|
kExampleSpropRawSps,
|
|
StartCode(),
|
|
kExampleSpropRawPps,
|
|
StartCode(),
|
|
{kIdr, 1, 2, 3}})));
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, IdrOnlyKeyframeWithoutSprop) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/true);
|
|
|
|
// Cannot fix biststream by prepending SPS and PPS because no sprop string is
|
|
// available. Request a key frame.
|
|
EXPECT_TRUE(
|
|
packet_buffer
|
|
.InsertPacket(
|
|
H264Packet(kH264SingleNalu).Idr({9, 9, 9}, 0).Marker().Build())
|
|
.buffer_cleared);
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, IdrOnlyKeyframeWithSpropAndUnknownPpsId) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/true);
|
|
packet_buffer.SetSpropParameterSets(kExampleSpropString);
|
|
|
|
// Cannot fix biststream because sprop string doesn't contain a PPS with given
|
|
// ID. Request a key frame.
|
|
EXPECT_TRUE(
|
|
packet_buffer
|
|
.InsertPacket(
|
|
H264Packet(kH264SingleNalu).Idr({9, 9, 9}, 1).Marker().Build())
|
|
.buffer_cleared);
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, IdrOnlyKeyframeInTheMiddle) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/true);
|
|
packet_buffer.SetSpropParameterSets(kExampleSpropString);
|
|
|
|
RTC_UNUSED(packet_buffer.InsertPacket(
|
|
H264Packet(kH264SingleNalu).Sps({1, 2, 3}, 1).SeqNum(0).Time(0).Build()));
|
|
RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264SingleNalu)
|
|
.Pps({4, 5, 6}, 1, 1)
|
|
.SeqNum(1)
|
|
.Time(0)
|
|
.Build()));
|
|
EXPECT_THAT(packet_buffer
|
|
.InsertPacket(H264Packet(kH264SingleNalu)
|
|
.Idr({7, 8, 9}, 1)
|
|
.SeqNum(2)
|
|
.Time(0)
|
|
.Marker()
|
|
.Build())
|
|
.packets,
|
|
SizeIs(3));
|
|
|
|
EXPECT_THAT(packet_buffer
|
|
.InsertPacket(H264Packet(kH264SingleNalu)
|
|
.Slice()
|
|
.SeqNum(3)
|
|
.Time(1)
|
|
.Marker()
|
|
.Build())
|
|
.packets,
|
|
SizeIs(1));
|
|
|
|
auto packets = packet_buffer
|
|
.InsertPacket(H264Packet(kH264SingleNalu)
|
|
.Idr({10, 11, 12}, 0)
|
|
.SeqNum(4)
|
|
.Time(2)
|
|
.Marker()
|
|
.Build())
|
|
.packets;
|
|
EXPECT_THAT(packets, SizeIs(1));
|
|
EXPECT_THAT(PacketPayload(packets[0]),
|
|
ElementsAreArray(FlatVector({StartCode(),
|
|
kExampleSpropRawSps,
|
|
StartCode(),
|
|
kExampleSpropRawPps,
|
|
StartCode(),
|
|
{kIdr, 10, 11, 12}})));
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, IdrIsNotKeyframe) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
EXPECT_THAT(
|
|
packet_buffer
|
|
.InsertPacket(H264Packet(kH264SingleNalu).Idr().Marker().Build())
|
|
.packets,
|
|
IsEmpty());
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, IdrIsKeyframeFuaRequiresFirstFragmet) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/true);
|
|
packet_buffer.SetSpropParameterSets(kExampleSpropString);
|
|
|
|
// Not marked as the first fragment
|
|
EXPECT_THAT(
|
|
packet_buffer
|
|
.InsertPacket(H264Packet(kH264FuA).Idr().SeqNum(0).Time(0).Build())
|
|
.packets,
|
|
IsEmpty());
|
|
|
|
EXPECT_THAT(
|
|
packet_buffer
|
|
.InsertPacket(
|
|
H264Packet(kH264FuA).Idr().SeqNum(1).Time(0).Marker().Build())
|
|
.packets,
|
|
IsEmpty());
|
|
|
|
// Marked as first fragment
|
|
EXPECT_THAT(packet_buffer
|
|
.InsertPacket(H264Packet(kH264FuA)
|
|
.Idr({9, 9, 9}, 0)
|
|
.SeqNum(2)
|
|
.Time(1)
|
|
.AsFirstFragment()
|
|
.Build())
|
|
.packets,
|
|
IsEmpty());
|
|
|
|
EXPECT_THAT(
|
|
packet_buffer
|
|
.InsertPacket(
|
|
H264Packet(kH264FuA).Idr().SeqNum(3).Time(1).Marker().Build())
|
|
.packets,
|
|
SizeIs(2));
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, SpsPpsIdrIsKeyframeSingleNalus) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
RTC_UNUSED(packet_buffer.InsertPacket(
|
|
H264Packet(kH264SingleNalu).Sps().SeqNum(0).Time(0).Build()));
|
|
RTC_UNUSED(packet_buffer.InsertPacket(
|
|
H264Packet(kH264SingleNalu).Pps().SeqNum(1).Time(0).Build()));
|
|
EXPECT_THAT(packet_buffer
|
|
.InsertPacket(H264Packet(kH264SingleNalu)
|
|
.Idr()
|
|
.SeqNum(2)
|
|
.Time(0)
|
|
.Marker()
|
|
.Build())
|
|
.packets,
|
|
SizeIs(3));
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, SpsPpsIdrIsKeyframeIgnoresSprop) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
// When h264_allow_idr_only_keyframes is false, sprop string should be
|
|
// ignored. Use in band parameter sets.
|
|
packet_buffer.SetSpropParameterSets(kExampleSpropString);
|
|
|
|
RTC_UNUSED(packet_buffer.InsertPacket(
|
|
H264Packet(kH264SingleNalu).Sps({1, 2, 3}, 0).SeqNum(0).Time(0).Build()));
|
|
RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264SingleNalu)
|
|
.Pps({4, 5, 6}, 0, 0)
|
|
.SeqNum(1)
|
|
.Time(0)
|
|
.Build()));
|
|
auto packets = packet_buffer
|
|
.InsertPacket(H264Packet(kH264SingleNalu)
|
|
.Idr({7, 8, 9}, 0)
|
|
.SeqNum(2)
|
|
.Time(0)
|
|
.Marker()
|
|
.Build())
|
|
.packets;
|
|
EXPECT_THAT(packets, SizeIs(3));
|
|
EXPECT_THAT(PacketPayload(packets[0]),
|
|
ElementsAreArray(FlatVector({StartCode(), {kSps, 1, 2, 3}})));
|
|
EXPECT_THAT(PacketPayload(packets[1]),
|
|
ElementsAreArray(FlatVector({StartCode(), {kPps, 4, 5, 6}})));
|
|
EXPECT_THAT(PacketPayload(packets[2]),
|
|
ElementsAreArray(FlatVector({StartCode(), {kIdr, 7, 8, 9}})));
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, PpsIdrIsNotKeyframeSingleNalus) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
RTC_UNUSED(packet_buffer.InsertPacket(
|
|
H264Packet(kH264SingleNalu).Pps().SeqNum(0).Time(0).Build()));
|
|
EXPECT_THAT(packet_buffer
|
|
.InsertPacket(H264Packet(kH264SingleNalu)
|
|
.Idr()
|
|
.SeqNum(1)
|
|
.Time(0)
|
|
.Marker()
|
|
.Build())
|
|
.packets,
|
|
IsEmpty());
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, SpsIdrIsNotKeyframeSingleNalus) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
RTC_UNUSED(packet_buffer.InsertPacket(
|
|
H264Packet(kH264SingleNalu).Sps().SeqNum(0).Time(0).Build()));
|
|
EXPECT_THAT(packet_buffer
|
|
.InsertPacket(H264Packet(kH264SingleNalu)
|
|
.Idr()
|
|
.SeqNum(1)
|
|
.Time(0)
|
|
.Marker()
|
|
.Build())
|
|
.packets,
|
|
IsEmpty());
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, SpsPpsIdrIsKeyframeStapA) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
EXPECT_THAT(packet_buffer
|
|
.InsertPacket(H264Packet(kH264StapA)
|
|
.Sps()
|
|
.Pps()
|
|
.Idr()
|
|
.SeqNum(0)
|
|
.Time(0)
|
|
.Marker()
|
|
.Build())
|
|
.packets,
|
|
SizeIs(1));
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, PpsIdrIsNotKeyframeStapA) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
EXPECT_THAT(packet_buffer
|
|
.InsertPacket(H264Packet(kH264StapA)
|
|
.Pps()
|
|
.Idr()
|
|
.SeqNum(0)
|
|
.Time(0)
|
|
.Marker()
|
|
.Build())
|
|
.packets,
|
|
IsEmpty());
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, SpsIdrIsNotKeyframeStapA) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
EXPECT_THAT(packet_buffer
|
|
.InsertPacket(H264Packet(kH264StapA)
|
|
.Sps()
|
|
.Idr()
|
|
.SeqNum(2)
|
|
.Time(2)
|
|
.Marker()
|
|
.Build())
|
|
.packets,
|
|
IsEmpty());
|
|
|
|
EXPECT_THAT(packet_buffer
|
|
.InsertPacket(H264Packet(kH264StapA)
|
|
.Sps()
|
|
.Pps()
|
|
.Idr()
|
|
.SeqNum(3)
|
|
.Time(3)
|
|
.Marker()
|
|
.Build())
|
|
.packets,
|
|
SizeIs(1));
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, InsertingSpsPpsLastCompletesKeyframe) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
RTC_UNUSED(packet_buffer.InsertPacket(
|
|
H264Packet(kH264SingleNalu).Idr().SeqNum(2).Time(1).Marker().Build()));
|
|
|
|
EXPECT_THAT(
|
|
packet_buffer
|
|
.InsertPacket(
|
|
H264Packet(kH264StapA).Sps().Pps().SeqNum(1).Time(1).Build())
|
|
.packets,
|
|
SizeIs(2));
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, InsertingMidFuaCompletesFrame) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
EXPECT_THAT(packet_buffer
|
|
.InsertPacket(H264Packet(kH264StapA)
|
|
.Sps()
|
|
.Pps()
|
|
.Idr()
|
|
.SeqNum(0)
|
|
.Time(0)
|
|
.Marker()
|
|
.Build())
|
|
.packets,
|
|
SizeIs(1));
|
|
|
|
RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264FuA)
|
|
.Slice()
|
|
.SeqNum(1)
|
|
.Time(1)
|
|
.AsFirstFragment()
|
|
.Build()));
|
|
RTC_UNUSED(packet_buffer.InsertPacket(
|
|
H264Packet(kH264FuA).Slice().SeqNum(3).Time(1).Marker().Build()));
|
|
EXPECT_THAT(
|
|
packet_buffer
|
|
.InsertPacket(H264Packet(kH264FuA).Slice().SeqNum(2).Time(1).Build())
|
|
.packets,
|
|
SizeIs(3));
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, SeqNumJumpDoesNotCompleteFrame) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
EXPECT_THAT(packet_buffer
|
|
.InsertPacket(H264Packet(kH264StapA)
|
|
.Sps()
|
|
.Pps()
|
|
.Idr()
|
|
.SeqNum(0)
|
|
.Time(0)
|
|
.Marker()
|
|
.Build())
|
|
.packets,
|
|
SizeIs(1));
|
|
|
|
EXPECT_THAT(
|
|
packet_buffer
|
|
.InsertPacket(H264Packet(kH264FuA).Slice().SeqNum(1).Time(1).Build())
|
|
.packets,
|
|
IsEmpty());
|
|
|
|
// Add `kBufferSize` to make the index of the sequence number wrap and end up
|
|
// where the packet with sequence number 2 would have ended up.
|
|
EXPECT_THAT(packet_buffer
|
|
.InsertPacket(H264Packet(kH264FuA)
|
|
.Slice()
|
|
.SeqNum(2 + kBufferSize)
|
|
.Time(3)
|
|
.Marker()
|
|
.Build())
|
|
.packets,
|
|
IsEmpty());
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, OldFramesAreNotCompletedAfterBufferWrap) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
EXPECT_THAT(packet_buffer
|
|
.InsertPacket(H264Packet(kH264SingleNalu)
|
|
.Slice()
|
|
.SeqNum(1)
|
|
.Time(1)
|
|
.Marker()
|
|
.Build())
|
|
.packets,
|
|
IsEmpty());
|
|
|
|
// New keyframe, preceedes packet with sequence number 1 in the buffer.
|
|
EXPECT_THAT(packet_buffer
|
|
.InsertPacket(H264Packet(kH264StapA)
|
|
.Sps()
|
|
.Pps()
|
|
.Idr()
|
|
.SeqNum(kBufferSize)
|
|
.Time(kBufferSize)
|
|
.Marker()
|
|
.Build())
|
|
.packets,
|
|
SizeIs(1));
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, OldPacketsDontBlockNewPackets) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
EXPECT_THAT(packet_buffer
|
|
.InsertPacket(H264Packet(kH264StapA)
|
|
.Sps()
|
|
.Pps()
|
|
.Idr()
|
|
.SeqNum(kBufferSize)
|
|
.Time(kBufferSize)
|
|
.Marker()
|
|
.Build())
|
|
.packets,
|
|
SizeIs(1));
|
|
|
|
RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264FuA)
|
|
.Slice()
|
|
.SeqNum(kBufferSize + 1)
|
|
.Time(kBufferSize + 1)
|
|
.AsFirstFragment()
|
|
.Build()));
|
|
|
|
RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264FuA)
|
|
.Slice()
|
|
.SeqNum(kBufferSize + 3)
|
|
.Time(kBufferSize + 1)
|
|
.Marker()
|
|
.Build()));
|
|
EXPECT_THAT(
|
|
packet_buffer
|
|
.InsertPacket(H264Packet(kH264FuA).Slice().SeqNum(2).Time(2).Build())
|
|
.packets,
|
|
IsEmpty());
|
|
|
|
EXPECT_THAT(packet_buffer
|
|
.InsertPacket(H264Packet(kH264FuA)
|
|
.Slice()
|
|
.SeqNum(kBufferSize + 2)
|
|
.Time(kBufferSize + 1)
|
|
.Build())
|
|
.packets,
|
|
SizeIs(3));
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, OldPacketDoesntCompleteFrame) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
EXPECT_THAT(packet_buffer
|
|
.InsertPacket(H264Packet(kH264StapA)
|
|
.Sps()
|
|
.Pps()
|
|
.Idr()
|
|
.SeqNum(kBufferSize)
|
|
.Time(kBufferSize)
|
|
.Marker()
|
|
.Build())
|
|
.packets,
|
|
SizeIs(1));
|
|
|
|
EXPECT_THAT(packet_buffer
|
|
.InsertPacket(H264Packet(kH264FuA)
|
|
.Slice()
|
|
.SeqNum(kBufferSize + 3)
|
|
.Time(kBufferSize + 1)
|
|
.Marker()
|
|
.Build())
|
|
.packets,
|
|
IsEmpty());
|
|
|
|
EXPECT_THAT(
|
|
packet_buffer
|
|
.InsertPacket(
|
|
H264Packet(kH264FuA).Slice().SeqNum(2).Time(2).Marker().Build())
|
|
.packets,
|
|
IsEmpty());
|
|
|
|
EXPECT_THAT(packet_buffer
|
|
.InsertPacket(H264Packet(kH264FuA)
|
|
.Slice()
|
|
.SeqNum(kBufferSize + 1)
|
|
.Time(kBufferSize + 1)
|
|
.AsFirstFragment()
|
|
.Build())
|
|
.packets,
|
|
IsEmpty());
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, FrameBoundariesAreSet) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
auto key = packet_buffer.InsertPacket(H264Packet(kH264StapA)
|
|
.Sps()
|
|
.Pps()
|
|
.Idr()
|
|
.SeqNum(1)
|
|
.Time(1)
|
|
.Marker()
|
|
.Build());
|
|
|
|
ASSERT_THAT(key.packets, SizeIs(1));
|
|
EXPECT_TRUE(key.packets[0]->video_header.is_first_packet_in_frame);
|
|
EXPECT_TRUE(key.packets[0]->video_header.is_last_packet_in_frame);
|
|
|
|
RTC_UNUSED(packet_buffer.InsertPacket(
|
|
H264Packet(kH264FuA).Slice().SeqNum(2).Time(2).Build()));
|
|
RTC_UNUSED(packet_buffer.InsertPacket(
|
|
H264Packet(kH264FuA).Slice().SeqNum(3).Time(2).Build()));
|
|
auto delta = packet_buffer.InsertPacket(
|
|
H264Packet(kH264FuA).Slice().SeqNum(4).Time(2).Marker().Build());
|
|
|
|
ASSERT_THAT(delta.packets, SizeIs(3));
|
|
EXPECT_TRUE(delta.packets[0]->video_header.is_first_packet_in_frame);
|
|
EXPECT_FALSE(delta.packets[0]->video_header.is_last_packet_in_frame);
|
|
|
|
EXPECT_FALSE(delta.packets[1]->video_header.is_first_packet_in_frame);
|
|
EXPECT_FALSE(delta.packets[1]->video_header.is_last_packet_in_frame);
|
|
|
|
EXPECT_FALSE(delta.packets[2]->video_header.is_first_packet_in_frame);
|
|
EXPECT_TRUE(delta.packets[2]->video_header.is_last_packet_in_frame);
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, ResolutionSetOnFirstPacket) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
RTC_UNUSED(packet_buffer.InsertPacket(
|
|
H264Packet(kH264SingleNalu).Aud().SeqNum(1).Time(1).Build()));
|
|
auto res = packet_buffer.InsertPacket(H264Packet(kH264StapA)
|
|
.SpsWithResolution({320, 240})
|
|
.Pps()
|
|
.Idr()
|
|
.SeqNum(2)
|
|
.Time(1)
|
|
.Marker()
|
|
.Build());
|
|
|
|
ASSERT_THAT(res.packets, SizeIs(2));
|
|
EXPECT_THAT(res.packets[0]->video_header.width, Eq(320));
|
|
EXPECT_THAT(res.packets[0]->video_header.height, Eq(240));
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, KeyframeAndDeltaFrameSetOnFirstPacket) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
RTC_UNUSED(packet_buffer.InsertPacket(
|
|
H264Packet(kH264SingleNalu).Aud().SeqNum(1).Time(1).Build()));
|
|
auto key = packet_buffer.InsertPacket(H264Packet(kH264StapA)
|
|
.Sps()
|
|
.Pps()
|
|
.Idr()
|
|
.SeqNum(2)
|
|
.Time(1)
|
|
.Marker()
|
|
.Build());
|
|
|
|
auto delta = packet_buffer.InsertPacket(
|
|
H264Packet(kH264SingleNalu).Slice().SeqNum(3).Time(2).Marker().Build());
|
|
|
|
ASSERT_THAT(key.packets, SizeIs(2));
|
|
EXPECT_THAT(key.packets[0]->video_header.frame_type,
|
|
Eq(VideoFrameType::kVideoFrameKey));
|
|
ASSERT_THAT(delta.packets, SizeIs(1));
|
|
EXPECT_THAT(delta.packets[0]->video_header.frame_type,
|
|
Eq(VideoFrameType::kVideoFrameDelta));
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, RtpSeqNumWrap) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
RTC_UNUSED(packet_buffer.InsertPacket(
|
|
H264Packet(kH264StapA).Sps().Pps().SeqNum(0xffff).Time(0).Build()));
|
|
|
|
RTC_UNUSED(packet_buffer.InsertPacket(
|
|
H264Packet(kH264FuA).Idr().SeqNum(0x1'0000).Time(0).Build()));
|
|
EXPECT_THAT(packet_buffer
|
|
.InsertPacket(H264Packet(kH264FuA)
|
|
.Idr()
|
|
.SeqNum(0x1'0001)
|
|
.Time(0)
|
|
.Marker()
|
|
.Build())
|
|
.packets,
|
|
SizeIs(3));
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, StapAFixedBitstream) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
auto packets = packet_buffer
|
|
.InsertPacket(H264Packet(kH264StapA)
|
|
.Sps({1, 2, 3})
|
|
.Pps({4, 5, 6})
|
|
.Idr({7, 8, 9})
|
|
.SeqNum(0)
|
|
.Time(0)
|
|
.Marker()
|
|
.Build())
|
|
.packets;
|
|
|
|
ASSERT_THAT(packets, SizeIs(1));
|
|
EXPECT_THAT(PacketPayload(packets[0]),
|
|
ElementsAreArray(FlatVector({StartCode(),
|
|
{kSps, 1, 2, 3},
|
|
StartCode(),
|
|
{kPps, 4, 5, 6},
|
|
StartCode(),
|
|
{kIdr, 7, 8, 9}})));
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, SingleNaluFixedBitstream) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
RTC_UNUSED(packet_buffer.InsertPacket(
|
|
H264Packet(kH264SingleNalu).Sps({1, 2, 3}).SeqNum(0).Time(0).Build()));
|
|
RTC_UNUSED(packet_buffer.InsertPacket(
|
|
H264Packet(kH264SingleNalu).Pps({4, 5, 6}).SeqNum(1).Time(0).Build()));
|
|
auto packets = packet_buffer
|
|
.InsertPacket(H264Packet(kH264SingleNalu)
|
|
.Idr({7, 8, 9})
|
|
.SeqNum(2)
|
|
.Time(0)
|
|
.Marker()
|
|
.Build())
|
|
.packets;
|
|
|
|
ASSERT_THAT(packets, SizeIs(3));
|
|
EXPECT_THAT(PacketPayload(packets[0]),
|
|
ElementsAreArray(FlatVector({StartCode(), {kSps, 1, 2, 3}})));
|
|
EXPECT_THAT(PacketPayload(packets[1]),
|
|
ElementsAreArray(FlatVector({StartCode(), {kPps, 4, 5, 6}})));
|
|
EXPECT_THAT(PacketPayload(packets[2]),
|
|
ElementsAreArray(FlatVector({StartCode(), {kIdr, 7, 8, 9}})));
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, StapaAndFuaFixedBitstream) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264StapA)
|
|
.Sps({1, 2, 3})
|
|
.Pps({4, 5, 6})
|
|
.SeqNum(0)
|
|
.Time(0)
|
|
.Build()));
|
|
RTC_UNUSED(packet_buffer.InsertPacket(H264Packet(kH264FuA)
|
|
.Idr({8, 8, 8})
|
|
.SeqNum(1)
|
|
.Time(0)
|
|
.AsFirstFragment()
|
|
.Build()));
|
|
auto packets = packet_buffer
|
|
.InsertPacket(H264Packet(kH264FuA)
|
|
.Idr({9, 9, 9})
|
|
.SeqNum(2)
|
|
.Time(0)
|
|
.Marker()
|
|
.Build())
|
|
.packets;
|
|
|
|
ASSERT_THAT(packets, SizeIs(3));
|
|
EXPECT_THAT(
|
|
PacketPayload(packets[0]),
|
|
ElementsAreArray(FlatVector(
|
|
{StartCode(), {kSps, 1, 2, 3}, StartCode(), {kPps, 4, 5, 6}})));
|
|
EXPECT_THAT(PacketPayload(packets[1]),
|
|
ElementsAreArray(FlatVector({StartCode(), {8, 8, 8}})));
|
|
// Third is a continuation of second, so only the payload is expected.
|
|
EXPECT_THAT(PacketPayload(packets[2]),
|
|
ElementsAreArray(FlatVector({{9, 9, 9}})));
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, FullPacketBufferDoesNotBlockKeyframe) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
for (int i = 0; i < kBufferSize; ++i) {
|
|
EXPECT_THAT(
|
|
packet_buffer
|
|
.InsertPacket(
|
|
H264Packet(kH264SingleNalu).Slice().SeqNum(i).Time(0).Build())
|
|
.packets,
|
|
IsEmpty());
|
|
}
|
|
|
|
EXPECT_THAT(packet_buffer
|
|
.InsertPacket(H264Packet(kH264StapA)
|
|
.Sps()
|
|
.Pps()
|
|
.Idr()
|
|
.SeqNum(kBufferSize)
|
|
.Time(1)
|
|
.Marker()
|
|
.Build())
|
|
.packets,
|
|
SizeIs(1));
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, AssembleFrameAfterReordering) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
EXPECT_THAT(packet_buffer
|
|
.InsertPacket(H264Packet(kH264StapA)
|
|
.Sps()
|
|
.Pps()
|
|
.Idr()
|
|
.SeqNum(2)
|
|
.Time(2)
|
|
.Marker()
|
|
.Build())
|
|
.packets,
|
|
SizeIs(1));
|
|
|
|
EXPECT_THAT(packet_buffer
|
|
.InsertPacket(H264Packet(kH264SingleNalu)
|
|
.Slice()
|
|
.SeqNum(1)
|
|
.Time(1)
|
|
.Marker()
|
|
.Build())
|
|
.packets,
|
|
IsEmpty());
|
|
|
|
EXPECT_THAT(packet_buffer
|
|
.InsertPacket(H264Packet(kH264StapA)
|
|
.Sps()
|
|
.Pps()
|
|
.Idr()
|
|
.SeqNum(0)
|
|
.Time(0)
|
|
.Marker()
|
|
.Build())
|
|
.packets,
|
|
SizeIs(2));
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, AssembleFrameAfterLoss) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
EXPECT_THAT(packet_buffer
|
|
.InsertPacket(H264Packet(kH264StapA)
|
|
.Sps()
|
|
.Pps()
|
|
.Idr()
|
|
.SeqNum(0)
|
|
.Time(0)
|
|
.Marker()
|
|
.Build())
|
|
.packets,
|
|
SizeIs(1));
|
|
|
|
EXPECT_THAT(packet_buffer
|
|
.InsertPacket(H264Packet(kH264StapA)
|
|
.Sps()
|
|
.Pps()
|
|
.Idr()
|
|
.SeqNum(2)
|
|
.Time(2)
|
|
.Marker()
|
|
.Build())
|
|
.packets,
|
|
SizeIs(1));
|
|
}
|
|
|
|
#ifdef RTC_ENABLE_H265
|
|
TEST(H26xPacketBufferTest, H265VpsSpsPpsIdrIsKeyframe) {
|
|
H26xPacketBuffer packet_buffer(/*allow_idr_only_keyframes=*/false);
|
|
|
|
EXPECT_THAT(
|
|
packet_buffer
|
|
.InsertPacket(H265Packet().Vps().Sps().Pps().Idr().Marker().Build())
|
|
.packets,
|
|
SizeIs(1));
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, H265IrapIsNotKeyframe) {
|
|
std::vector<H265::NaluType> irap_types = {
|
|
H265::NaluType::kBlaWLp, H265::NaluType::kBlaWRadl,
|
|
H265::NaluType::kBlaNLp, H265::NaluType::kIdrWRadl,
|
|
H265::NaluType::kIdrNLp, H265::NaluType::kCra,
|
|
H265::NaluType::kRsvIrapVcl23};
|
|
for (const H265::NaluType type : irap_types) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
EXPECT_THAT(
|
|
packet_buffer.InsertPacket(H265Packet().Slice(type).Marker().Build())
|
|
.packets,
|
|
IsEmpty());
|
|
}
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, H265IdrIsNotKeyFrame) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
EXPECT_THAT(
|
|
packet_buffer.InsertPacket(H265Packet().Idr().Marker().Build()).packets,
|
|
IsEmpty());
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, H265IdrIsNotKeyFrameEvenWithSprop) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/true);
|
|
packet_buffer.SetSpropParameterSets(kExampleSpropString);
|
|
|
|
EXPECT_THAT(
|
|
packet_buffer.InsertPacket(H265Packet().Idr().Marker().Build()).packets,
|
|
IsEmpty());
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, H265SpsPpsIdrIsNotKeyFrame) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
EXPECT_THAT(packet_buffer
|
|
.InsertPacket(H265Packet().Sps().Pps().Idr().Marker().Build())
|
|
.packets,
|
|
IsEmpty());
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, H265VpsPpsIdrIsNotKeyFrame) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
EXPECT_THAT(packet_buffer
|
|
.InsertPacket(H265Packet().Vps().Pps().Idr().Marker().Build())
|
|
.packets,
|
|
IsEmpty());
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, H265VpsSpsIdrIsNotKeyFrame) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
EXPECT_THAT(packet_buffer
|
|
.InsertPacket(H265Packet().Vps().Sps().Idr().Marker().Build())
|
|
.packets,
|
|
IsEmpty());
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, H265VpsIdrIsNotKeyFrame) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
EXPECT_THAT(
|
|
packet_buffer.InsertPacket(H265Packet().Vps().Idr().Marker().Build())
|
|
.packets,
|
|
IsEmpty());
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, H265SpsIdrIsNotKeyFrame) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
EXPECT_THAT(
|
|
packet_buffer.InsertPacket(H265Packet().Sps().Idr().Marker().Build())
|
|
.packets,
|
|
IsEmpty());
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, H265PpsIdrIsNotKeyFrame) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
EXPECT_THAT(
|
|
packet_buffer.InsertPacket(H265Packet().Pps().Idr().Marker().Build())
|
|
.packets,
|
|
IsEmpty());
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, H265ResolutionSetOnSpsPacket) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
RTC_UNUSED(
|
|
packet_buffer.InsertPacket(H265Packet().Aud().SeqNum(1).Time(1).Build()));
|
|
auto res = packet_buffer.InsertPacket(H265Packet()
|
|
.Vps()
|
|
.SpsWithResolution({320, 240})
|
|
.Pps()
|
|
.Idr()
|
|
.SeqNum(2)
|
|
.Time(1)
|
|
.Marker()
|
|
.Build());
|
|
|
|
ASSERT_THAT(res.packets, SizeIs(2));
|
|
EXPECT_THAT(res.packets[0]->video_header.width, Eq(320));
|
|
EXPECT_THAT(res.packets[0]->video_header.height, Eq(240));
|
|
}
|
|
|
|
TEST(H26xPacketBufferTest, H265InsertingVpsSpsPpsLastCompletesKeyframe) {
|
|
H26xPacketBuffer packet_buffer(/*h264_allow_idr_only_keyframes=*/false);
|
|
|
|
RTC_UNUSED(packet_buffer.InsertPacket(
|
|
H265Packet().Idr().SeqNum(2).Time(1).Marker().Build()));
|
|
|
|
EXPECT_THAT(packet_buffer
|
|
.InsertPacket(
|
|
H265Packet().Vps().Sps().Pps().SeqNum(1).Time(1).Build())
|
|
.packets,
|
|
SizeIs(2));
|
|
}
|
|
#endif // RTC_ENABLE_H265
|
|
|
|
} // namespace
|
|
} // namespace webrtc
|